initial import of main veilid core

This commit is contained in:
John Smith
2021-11-22 11:28:30 -05:00
parent c4cd54e020
commit 9e94a6a96f
218 changed files with 34880 additions and 1 deletions
+4
View File
@@ -0,0 +1,4 @@
# exclude everything
tmp/*
# exception to the rule
!tmp/.gitkeep
+16
View File
@@ -0,0 +1,16 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
/.idea/deploymentTargetDropDown.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+1
View File
@@ -0,0 +1 @@
VeilidCore Tests
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="disableWrapperSourceDistributionNotification" value="true" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="1.8" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../../.." vcs="Git" />
</component>
</project>
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>VeilidCore Tests</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>0</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
@@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=/opt/android-studio/jre
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
@@ -0,0 +1,4 @@
/build
/.cxx
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>VeilidCore Tests-app</name>
<comment>Project VeilidCore Tests-app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1635633714053</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
@@ -0,0 +1,2 @@
connection.project.dir=..
eclipse.preferences.version=1
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.1)
project(cpplink CXX)
add_library(cpplink cpplink.cpp)
@@ -0,0 +1,85 @@
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.veilid.veilidcore.veilidcore_android_tests"
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'arm64-v8a', 'x86', 'x86_64'
}
// Required to copy libc++_shared.so
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
targets "cpplink"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
ndkVersion '22.0.7026061'
// Required to copy libc++_shared.so
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
cargo {
module = "../../../.."
libname = "veilid_core"
targets = ["arm64", "x86", "x86_64"]
prebuiltToolchains = true
profile = gradle.startParameter.taskNames.any{it.toLowerCase().contains("debug")} ? "debug" : "release"
features {
defaultAnd("android_tests")
}
}
afterEvaluate {
// The `cargoBuild` task isn't available until after evaluation.
android.applicationVariants.all { variant ->
def productFlavor = ""
variant.productFlavors.each {
productFlavor += "${it.name.capitalize()}"
}
def buildType = "${variant.buildType.name.capitalize()}"
tasks["generate${productFlavor}${buildType}Assets"].dependsOn(tasks["cargoBuild"])
}
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.veilid.veilidcore.veilidcore_android_tests">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.VeilidCoreTests">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,37 @@
package com.veilid.veilidcore.veilidcore_android_tests;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("veilid_core");
}
private static native void run_tests(Context context);
private Thread testThread;
class TestThread extends Thread {
private Context context;
TestThread(Context context) {
this.context = context;
}
public void run() {
run_tests(this.context);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.testThread = new TestThread(this);
this.testThread.start();
}
}
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.VeilidCoreTests" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">VeilidCore Tests</string>
</resources>
@@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.VeilidCoreTests" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
@@ -0,0 +1,28 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id "org.mozilla.rust-android-gradle.rust-android" version "0.8.6"
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
@@ -0,0 +1,19 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
Binary file not shown.
@@ -0,0 +1,6 @@
#Mon Jun 21 14:26:26 PDT 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
+84
View File
@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,2 @@
include ':app'
rootProject.name = "VeilidCore Tests"
+8
View File
@@ -0,0 +1,8 @@
pub mod test_connection_table;
pub mod test_crypto;
pub mod test_dht_key;
pub mod test_envelope_receipt;
pub mod test_host_interface;
pub mod test_table_store;
pub mod test_veilid_config;
pub mod test_veilid_core;
@@ -0,0 +1,104 @@
use crate::connection_table::*;
use crate::intf::*;
use crate::xx::*;
use crate::*;
pub async fn test_add_get_remove() {
let table = ConnectionTable::new();
let c1 = NetworkConnection::Dummy(DummyNetworkConnection {});
let c2 = NetworkConnection::Dummy(DummyNetworkConnection {});
let c3 = NetworkConnection::Dummy(DummyNetworkConnection {});
let a1 = ConnectionDescriptor::new_no_local(PeerAddress::new(
Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)),
8080,
ProtocolType::TCP,
));
let a2 = ConnectionDescriptor::new_no_local(PeerAddress::new(
Address::IPV4(Ipv4Addr::new(127, 0, 0, 1)),
8080,
ProtocolType::TCP,
));
let a3 = ConnectionDescriptor::new(
PeerAddress::new(
Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
8090,
ProtocolType::TCP,
),
SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
8080,
0,
0,
)),
);
let a4 = ConnectionDescriptor::new(
PeerAddress::new(
Address::IPV6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
8090,
ProtocolType::TCP,
),
SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 1),
8080,
0,
0,
)),
);
let a5 = ConnectionDescriptor::new(
PeerAddress::new(
Address::Hostname("example.com".to_owned()),
8090,
ProtocolType::WSS,
),
SocketAddr::V6(SocketAddrV6::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
8080,
0,
0,
)),
);
assert_eq!(a1, a2);
assert_ne!(a3, a4);
assert_ne!(a4, a5);
assert_eq!(table.connection_count(), 0);
assert_eq!(table.get_connection(&a1), None);
let entry1 = table.add_connection(a1.clone(), c1.clone()).unwrap();
assert_eq!(table.connection_count(), 1);
assert_eq!(table.remove_connection(&a3), Err(()));
assert_eq!(table.remove_connection(&a4), Err(()));
assert_eq!(table.connection_count(), 1);
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.connection_count(), 1);
assert_eq!(table.add_connection(a1.clone(), c1.clone()), Err(()));
assert_eq!(table.add_connection(a1.clone(), c2.clone()), Err(()));
assert_eq!(table.connection_count(), 1);
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.get_connection(&a1), Some(entry1.clone()));
assert_eq!(table.connection_count(), 1);
assert_eq!(table.remove_connection(&a2), Ok(entry1.clone()));
assert_eq!(table.connection_count(), 0);
assert_eq!(table.remove_connection(&a2), Err(()));
assert_eq!(table.connection_count(), 0);
assert_eq!(table.get_connection(&a2), None);
assert_eq!(table.get_connection(&a1), None);
assert_eq!(table.connection_count(), 0);
let entry2 = table.add_connection(a1.clone(), c1.clone()).unwrap();
assert_eq!(table.add_connection(a2.clone(), c1), Err(()));
let entry3 = table.add_connection(a3.clone(), c2.clone()).unwrap();
let entry4 = table.add_connection(a4.clone(), c3.clone()).unwrap();
assert_eq!(table.connection_count(), 3);
assert_eq!(table.remove_connection(&a2), Ok(entry2.clone()));
assert_eq!(table.remove_connection(&a3), Ok(entry3.clone()));
assert_eq!(table.remove_connection(&a4), Ok(entry4.clone()));
assert_eq!(table.connection_count(), 0);
}
pub async fn test_all() {
test_add_get_remove().await;
}
+140
View File
@@ -0,0 +1,140 @@
use super::test_veilid_config::*;
use crate::dht::crypto::*;
use crate::dht::key;
use crate::xx::*;
use crate::*;
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. ";
fn setup_veilid_core() -> VeilidCoreSetup {
VeilidCoreSetup {
state_change_callback: Arc::new(
move |change: VeilidStateChange| -> SystemPinBoxFuture<()> {
Box::pin(async move {
trace!("state_change_callback: {:?}", change);
})
},
),
config_callback: Arc::new(config_callback),
}
}
async fn startup(core: VeilidCore) -> VeilidAPI {
trace!("test_table_store: starting");
let api = core
.startup(setup_veilid_core())
.await
.expect("startup failed");
api
}
async fn shutdown(api: VeilidAPI) {
trace!("test_table_store: shutting down");
api.shutdown().await;
trace!("test_table_store: finished");
}
pub async fn test_enc_dec() {
trace!("test_enc_dec");
let n1 = Crypto::get_random_nonce();
let n2 = loop {
let n = Crypto::get_random_nonce();
if n != n1 {
break n;
}
};
let ss1 = Crypto::get_random_secret();
let ss2 = loop {
let ss = Crypto::get_random_secret();
if ss != ss1 {
break ss;
}
};
let mut body = LOREM_IPSUM.to_vec();
let body2 = body.clone();
let size_before_encrypt = body.len();
assert!(
Crypto::encrypt_in_place(&mut body, &n1, &ss1, None).is_ok(),
"encrypt should succeed"
);
let size_after_encrypt = body.len();
assert!(
size_after_encrypt - size_before_encrypt == ENCRYPTION_OVERHEAD,
"overhead should match"
);
let mut body3 = body.clone();
let mut body4 = body.clone();
let mut body5 = body.clone();
assert!(
Crypto::decrypt_in_place(&mut body, &n1, &ss1, None).is_ok(),
"decrypt should succeed"
);
assert_eq!(body, body2, "results should be the same");
assert!(
Crypto::decrypt_in_place(&mut body3, &n2, &ss1, None).is_err(),
"decrypt with wrong nonce should fail"
);
assert_ne!(body3, body, "failure changes data");
assert!(
Crypto::decrypt_in_place(&mut body4, &n1, &ss2, None).is_err(),
"decrypt with wrong secret should fail"
);
assert_ne!(body4, body, "failure changes data");
assert!(
Crypto::decrypt_in_place(&mut body5, &n1, &ss2, Some(b"foobar")).is_err(),
"decrypt with wrong associated data should fail"
);
assert_ne!(body5, body, "failure changes data");
assert!(
Crypto::decrypt(LOREM_IPSUM, &n1, &ss1, None).is_err(),
"should fail authentication"
);
let body5 = Crypto::encrypt(LOREM_IPSUM, &n1, &ss1, None).unwrap();
let body6 = Crypto::decrypt(&body5, &n1, &ss1, None).unwrap();
let body7 = Crypto::encrypt(LOREM_IPSUM, &n1, &ss1, None).unwrap();
assert_eq!(body6, LOREM_IPSUM);
assert_eq!(body5, body7);
}
pub async fn test_dh(crypto: Crypto) {
trace!("test_dh");
let (dht_key, dht_key_secret) = key::generate_secret();
let (dht_key2, dht_key_secret2) = key::generate_secret();
let r1 = Crypto::compute_dh(&dht_key, &dht_key_secret2).unwrap();
let r2 = Crypto::compute_dh(&dht_key2, &dht_key_secret).unwrap();
let r3 = Crypto::compute_dh(&dht_key, &dht_key_secret2).unwrap();
let r4 = Crypto::compute_dh(&dht_key2, &dht_key_secret).unwrap();
assert_eq!(r1, r2);
assert_eq!(r3, r4);
assert_eq!(r2, r3);
trace!("dh: {:?}", r1);
// test cache
let r5 = crypto.cached_dh(&dht_key, &dht_key_secret2).unwrap();
let r6 = crypto.cached_dh(&dht_key2, &dht_key_secret).unwrap();
let r7 = crypto.cached_dh(&dht_key, &dht_key_secret2).unwrap();
let r8 = crypto.cached_dh(&dht_key2, &dht_key_secret).unwrap();
assert_eq!(r1, r5);
assert_eq!(r2, r6);
assert_eq!(r3, r7);
assert_eq!(r4, r8);
trace!("cached_dh: {:?}", r5);
}
pub async fn test_all() {
let core = VeilidCore::new();
let api = startup(core.clone()).await;
let crypto = core.crypto();
test_enc_dec().await;
test_dh(crypto).await;
shutdown(api.clone()).await;
assert_eq!(api.is_shutdown(), true);
}
@@ -0,0 +1,323 @@
use crate::dht::key;
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. ";
static CHEEZBURGER: &str = "I can has cheezburger";
static EMPTY_KEY: [u8; key::DHT_KEY_LENGTH] = [0u8; key::DHT_KEY_LENGTH];
static EMPTY_KEY_SECRET: [u8; key::DHT_KEY_SECRET_LENGTH] = [0u8; key::DHT_KEY_SECRET_LENGTH];
pub async fn test_generate_secret() {
// Verify keys generate
let (dht_key, dht_key_secret) = key::generate_secret();
let (dht_key2, dht_key_secret2) = key::generate_secret();
// Verify byte patterns are different between public and secret
assert_ne!(dht_key.bytes, dht_key_secret.bytes);
assert_ne!(dht_key2.bytes, dht_key_secret2.bytes);
// Verify the keys and secrets are different across keypairs
assert_ne!(dht_key, dht_key2);
assert_ne!(dht_key_secret, dht_key_secret2);
}
pub async fn test_sign_and_verify() {
// Make two keys
let (dht_key, dht_key_secret) = key::generate_secret();
let (dht_key2, dht_key_secret2) = key::generate_secret();
// Sign the same message twice
let dht_sig = key::sign(&dht_key, &dht_key_secret, LOREM_IPSUM.as_bytes()).unwrap();
trace!("dht_sig: {:?}", dht_sig);
let dht_sig_b = key::sign(&dht_key, &dht_key_secret, LOREM_IPSUM.as_bytes()).unwrap();
// Sign a second message
let dht_sig_c = key::sign(&dht_key, &dht_key_secret, CHEEZBURGER.as_bytes()).unwrap();
trace!("dht_sig_c: {:?}", dht_sig_c);
// Verify they are the same signature
assert_eq!(dht_sig, dht_sig_b);
// Sign the same message with a different key
let dht_sig2 = key::sign(&dht_key2, &dht_key_secret2, LOREM_IPSUM.as_bytes()).unwrap();
// Verify a different key gives a different signature
assert_ne!(dht_sig2, dht_sig_b);
// Try using the wrong secret to sign
let a1 = key::sign(&dht_key, &dht_key_secret, LOREM_IPSUM.as_bytes()).unwrap();
let a2 = key::sign(&dht_key2, &dht_key_secret2, LOREM_IPSUM.as_bytes()).unwrap();
let b1 = key::sign(&dht_key, &dht_key_secret2, LOREM_IPSUM.as_bytes()).unwrap();
let b2 = key::sign(&dht_key2, &dht_key_secret, LOREM_IPSUM.as_bytes()).unwrap();
assert_ne!(a1, b1);
assert_ne!(a2, b2);
assert_ne!(a1, b2);
assert_ne!(a2, b1);
assert_ne!(a1, a2);
assert_ne!(b1, b2);
assert_ne!(a1, b2);
assert_ne!(b1, a2);
assert_eq!(key::verify(&dht_key, LOREM_IPSUM.as_bytes(), &a1), Ok(()));
assert_eq!(key::verify(&dht_key2, LOREM_IPSUM.as_bytes(), &a2), Ok(()));
assert_eq!(
key::verify(&dht_key, LOREM_IPSUM.as_bytes(), &b1),
Err("Verification failed".to_owned())
);
assert_eq!(
key::verify(&dht_key2, LOREM_IPSUM.as_bytes(), &b2),
Err("Verification failed".to_owned())
);
// Try verifications that should work
assert_eq!(
key::verify(&dht_key, LOREM_IPSUM.as_bytes(), &dht_sig),
Ok(())
);
assert_eq!(
key::verify(&dht_key, LOREM_IPSUM.as_bytes(), &dht_sig_b),
Ok(())
);
assert_eq!(
key::verify(&dht_key2, LOREM_IPSUM.as_bytes(), &dht_sig2),
Ok(())
);
assert_eq!(
key::verify(&dht_key, CHEEZBURGER.as_bytes(), &dht_sig_c),
Ok(())
);
// Try verifications that shouldn't work
assert_eq!(
key::verify(&dht_key2, LOREM_IPSUM.as_bytes(), &dht_sig),
Err("Verification failed".to_owned())
);
assert_eq!(
key::verify(&dht_key, LOREM_IPSUM.as_bytes(), &dht_sig2),
Err("Verification failed".to_owned())
);
assert_eq!(
key::verify(&dht_key2, CHEEZBURGER.as_bytes(), &dht_sig_c),
Err("Verification failed".to_owned())
);
assert_eq!(
key::verify(&dht_key, CHEEZBURGER.as_bytes(), &dht_sig),
Err("Verification failed".to_owned())
);
}
pub async fn test_key_conversions() {
// Test default key
let (dht_key, dht_key_secret) = (key::DHTKey::default(), key::DHTKeySecret::default());
assert_eq!(dht_key.bytes, EMPTY_KEY);
assert_eq!(dht_key.valid, false);
assert_eq!(dht_key_secret.bytes, EMPTY_KEY_SECRET);
assert_eq!(dht_key_secret.valid, false);
let dht_key_string = String::from(&dht_key);
trace!("dht_key_string: {:?}", dht_key_string);
let dht_key_string2 = String::from(&dht_key);
trace!("dht_key_string2: {:?}", dht_key_string2);
assert_eq!(dht_key_string, dht_key_string2);
let dht_key_secret_string = String::from(&dht_key_secret);
trace!("dht_key_secret_string: {:?}", dht_key_secret_string);
assert_eq!(dht_key_secret_string, dht_key_string);
// Make different keys
let (dht_key2, dht_key_secret2) = key::generate_secret();
trace!("dht_key2: {:?}", dht_key2);
trace!("dht_key_secret2: {:?}", dht_key_secret2);
let (dht_key3, _dht_key_secret3) = key::generate_secret();
trace!("dht_key3: {:?}", dht_key3);
trace!("_dht_key_secret3: {:?}", _dht_key_secret3);
let dht_key2_string = String::from(&dht_key2);
let dht_key2_string2 = String::from(&dht_key2);
let dht_key3_string = String::from(&dht_key3);
assert_eq!(dht_key2_string, dht_key2_string2);
assert_ne!(dht_key3_string, dht_key2_string);
let dht_key_secret2_string = String::from(&dht_key_secret2);
assert_ne!(dht_key_secret2_string, dht_key_secret_string);
assert_ne!(dht_key_secret2_string, dht_key2_string);
// Assert they convert back correctly
let dht_key_back = key::DHTKey::try_from(dht_key_string.as_str()).unwrap();
let dht_key_back2 = key::DHTKey::try_from(dht_key_string2.as_str()).unwrap();
assert_eq!(dht_key_back, dht_key_back2);
assert_eq!(dht_key_back, dht_key);
assert_eq!(dht_key_back2, dht_key);
let dht_key_secret_back = key::DHTKeySecret::try_from(dht_key_secret_string.as_str()).unwrap();
assert_eq!(dht_key_secret_back, dht_key_secret);
let dht_key2_back = key::DHTKey::try_from(dht_key2_string.as_str()).unwrap();
let dht_key2_back2 = key::DHTKey::try_from(dht_key2_string2.as_str()).unwrap();
assert_eq!(dht_key2_back, dht_key2_back2);
assert_eq!(dht_key2_back, dht_key2);
assert_eq!(dht_key2_back2, dht_key2);
let dht_key_secret2_back =
key::DHTKeySecret::try_from(dht_key_secret2_string.as_str()).unwrap();
assert_eq!(dht_key_secret2_back, dht_key_secret2);
// Assert string roundtrip
assert_eq!(String::from(&dht_key2_back), dht_key2_string);
assert!(key::DHTKey::try_from("") == Ok(key::DHTKey::default()));
assert!(key::DHTKeySecret::try_from("") == Ok(key::DHTKeySecret::default()));
// These conversions should fail
assert!(key::DHTKey::try_from("whatever").is_err());
assert!(key::DHTKeySecret::try_from("whatever").is_err());
assert!(key::DHTKey::try_from(" ").is_err());
assert!(key::DHTKeySecret::try_from(" ").is_err());
assert!(key::DHTKey::try_from(
"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
)
.is_err());
assert!(key::DHTKeySecret::try_from(
"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
)
.is_err());
}
pub async fn test_encode_decode() {
let dht_key = key::DHTKey::try_decode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").unwrap();
let dht_key_secret =
key::DHTKeySecret::try_decode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA").unwrap();
let dht_key_b = key::DHTKey::new(EMPTY_KEY);
let dht_key_secret_b = key::DHTKeySecret::new(EMPTY_KEY_SECRET);
assert_eq!(dht_key, dht_key_b);
assert_eq!(dht_key_secret, dht_key_secret_b);
let (dht_key2, dht_key_secret2) = key::generate_secret();
let e1 = dht_key.encode();
trace!("e1: {:?}", e1);
assert_eq!(e1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".to_owned());
let e1s = dht_key_secret.encode();
trace!("e1s: {:?}", e1s);
let e2 = dht_key2.encode();
trace!("e2: {:?}", e2);
let e2s = dht_key_secret2.encode();
trace!("e2s: {:?}", e2s);
let d1 = key::DHTKey::try_decode(e1.as_str()).unwrap();
trace!("d1: {:?}", d1);
assert_eq!(dht_key, d1);
let d1s = key::DHTKeySecret::try_decode(e1s.as_str()).unwrap();
trace!("d1s: {:?}", d1s);
assert_eq!(dht_key_secret, d1s);
let d2 = key::DHTKey::try_decode(e2.as_str()).unwrap();
trace!("d2: {:?}", d2);
assert_eq!(dht_key2, d2);
let d2s = key::DHTKeySecret::try_decode(e2s.as_str()).unwrap();
trace!("d2s: {:?}", d2s);
assert_eq!(dht_key_secret2, d2s);
// Failures
let f1 = key::DHTKeySecret::try_decode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
assert_eq!(f1, Err("Incorrect length in decode".to_owned()));
let f2 = key::DHTKeySecret::try_decode("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&");
assert_eq!(f2, Err("Failed to decode".to_owned()));
}
async fn test_hash() {
let mut s = BTreeSet::<key::DHTKey>::new();
let k1 = key::generate_hash("abc".as_bytes());
let k2 = key::generate_hash("abcd".as_bytes());
let k3 = key::generate_hash("".as_bytes());
let k4 = key::generate_hash(" ".as_bytes());
let k5 = key::generate_hash(LOREM_IPSUM.as_bytes());
let k6 = key::generate_hash(CHEEZBURGER.as_bytes());
s.insert(k1);
s.insert(k2);
s.insert(k3);
s.insert(k4);
s.insert(k5);
s.insert(k6);
assert_eq!(s.len(), 6);
let v1 = key::generate_hash("abc".as_bytes());
let v2 = key::generate_hash("abcd".as_bytes());
let v3 = key::generate_hash("".as_bytes());
let v4 = key::generate_hash(" ".as_bytes());
let v5 = key::generate_hash(LOREM_IPSUM.as_bytes());
let v6 = key::generate_hash(CHEEZBURGER.as_bytes());
assert_eq!(k1, v1);
assert_eq!(k2, v2);
assert_eq!(k3, v3);
assert_eq!(k4, v4);
assert_eq!(k5, v5);
assert_eq!(k6, v6);
key::validate_hash("abc".as_bytes(), &v1);
key::validate_hash("abcd".as_bytes(), &v2);
key::validate_hash("".as_bytes(), &v3);
key::validate_hash(" ".as_bytes(), &v4);
key::validate_hash(LOREM_IPSUM.as_bytes(), &v5);
key::validate_hash(CHEEZBURGER.as_bytes(), &v6);
}
async fn test_operations() {
let k1 = key::generate_hash(LOREM_IPSUM.as_bytes());
let k2 = key::generate_hash(CHEEZBURGER.as_bytes());
let k3 = key::generate_hash("abc".as_bytes());
// Get distance
let d1 = key::distance(&k1, &k2);
let d2 = key::distance(&k2, &k1);
let d3 = key::distance(&k1, &k3);
let d4 = key::distance(&k2, &k3);
trace!("d1={:?}", d1);
trace!("d2={:?}", d2);
trace!("d3={:?}", d3);
trace!("d4={:?}", d4);
// Verify commutativity
assert_eq!(d1, d2);
assert!(d1 <= d2);
assert!(d1 >= d2);
assert!(!(d1 < d2));
assert!(!(d1 > d2));
assert_eq!(d2, d1);
assert!(d2 <= d1);
assert!(d2 >= d1);
assert!(!(d2 < d1));
assert!(!(d2 > d1));
// Verify nibbles
assert_eq!(d1.nibble(0), 0x9u8);
assert_eq!(d1.nibble(1), 0x4u8);
assert_eq!(d1.nibble(2), 0x3u8);
assert_eq!(d1.nibble(3), 0x6u8);
assert_eq!(d1.nibble(63), 0x6u8);
assert_eq!(d1.first_nonzero_nibble(), Some((0, 0x9u8)));
assert_eq!(d2.first_nonzero_nibble(), Some((0, 0x9u8)));
assert_eq!(d3.first_nonzero_nibble(), Some((1, 0x4u8)));
assert_eq!(d4.first_nonzero_nibble(), Some((0, 0x9u8)));
// Verify bits
assert_eq!(d1.bit(0), true);
assert_eq!(d1.bit(1), false);
assert_eq!(d1.bit(7), false);
assert_eq!(d1.bit(8), false);
assert_eq!(d1.bit(14), true);
assert_eq!(d1.bit(15), false);
assert_eq!(d1.bit(254), true);
assert_eq!(d1.bit(255), false);
assert_eq!(d1.first_nonzero_bit(), Some(0));
assert_eq!(d2.first_nonzero_bit(), Some(0));
assert_eq!(d3.first_nonzero_bit(), Some(5));
assert_eq!(d4.first_nonzero_bit(), Some(0));
}
pub async fn test_all() {
test_generate_secret().await;
test_sign_and_verify().await;
test_key_conversions().await;
test_encode_decode().await;
test_hash().await;
test_operations().await;
}
@@ -0,0 +1,83 @@
use super::test_veilid_config::*;
use crate::dht::crypto::*;
use crate::dht::envelope::*;
use crate::dht::key::*;
use crate::dht::receipt::*;
use crate::xx::*;
use crate::*;
pub async fn test_envelope_round_trip() {
info!("--- test envelope round trip ---");
let veilid_core = VeilidCore::new();
let api = veilid_core
.startup(setup_veilid_core())
.await
.expect("startup failed");
// Get crypto
let crypto = veilid_core.crypto();
// Create envelope
let ts = 0x12345678ABCDEF69u64;
let nonce = Crypto::get_random_nonce();
let (sender_id, sender_secret) = generate_secret();
let (recipient_id, recipient_secret) = generate_secret();
let envelope = Envelope::new(0, ts, nonce, sender_id, recipient_id);
// Create arbitrary body
let body = b"This is an arbitrary body";
// Serialize to bytes
let enc_data = envelope
.to_encrypted_data(crypto.clone(), body, &sender_secret)
.expect("failed to encrypt data");
// Deserialize from bytes
let envelope2 =
Envelope::from_data(&enc_data).expect("failed to deserialize envelope from data");
let body2 = envelope2
.decrypt_body(crypto.clone(), &enc_data, &recipient_secret)
.expect("failed to decrypt envelope body");
envelope2
.decrypt_body(crypto.clone(), &enc_data, &sender_secret)
.expect_err("should have failed to decrypt using wrong secret");
// Compare envelope and body
assert_eq!(envelope, envelope2);
assert_eq!(body.to_vec(), body2);
api.shutdown().await;
}
pub async fn test_receipt_round_trip() {
info!("--- test receipt round trip ---");
// Create arbitrary body
let body = b"This is an arbitrary body";
// Create receipt
let nonce = Crypto::get_random_nonce();
let (sender_id, sender_secret) = generate_secret();
let receipt = Receipt::try_new(0, nonce, sender_id, body).expect("should not fail");
// Serialize to bytes
let mut enc_data = receipt
.to_signed_data(&sender_secret)
.expect("failed to make signed data");
// Deserialize from bytes
let receipt2 =
Receipt::from_signed_data(&enc_data).expect("failed to deserialize envelope from data");
// Should not validate even when a single bit is changed
enc_data[5] = 0x01;
Receipt::from_signed_data(&enc_data)
.expect_err("should have failed to decrypt using wrong secret");
// Compare receipts
assert_eq!(receipt, receipt2);
}
pub async fn test_all() {
test_envelope_round_trip().await;
test_receipt_round_trip().await;
}
@@ -0,0 +1,533 @@
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 = intf::get_timestamp();
let t2 = intf::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 = intf::spawn(async move {
intf::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 = intf::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);
});
intf::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 = intf::spawn(async move {
assert_eq!(i1.await, 1u32);
assert_eq!(i2.await, 2u32);
});
intf::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 = intf::spawn(async move {
assert_eq!(j1.await, 1u32);
assert_eq!(j2.await, 2u32);
});
intf::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 = intf::spawn(async move {
intf::sleep(1000).await;
e1_c1.resolve(3u32);
});
assert_eq!(i1.await, ());
assert_eq!(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 = intf::spawn(async move {
let i5 = e1.instance();
let i6 = e1.instance();
assert_eq!(i1.await, ());
assert_eq!(i5.await, ());
assert_eq!(i6.await, ());
});
intf::sleep(1000).await;
let resolved = e1_c1.resolve(4u16);
drop(i2);
drop(i3);
assert_eq!(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 = intf::spawn(async move {
assert_eq!(i1.await, ());
assert_eq!(i2.await, ());
});
intf::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 = intf::spawn(async move {
assert_eq!(j1.await, ());
assert_eq!(j2.await, ());
});
intf::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 = intf::spawn(async move {
intf::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 = intf::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);
});
intf::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 = intf::spawn(async move {
assert_eq!(i1.await, 5);
assert_eq!(i2.await, 5);
});
intf::sleep(1000).await;
e1_c1.resolve(5u32).await;
jh.await;
e1_c1.reset();
//
let j1 = e1.instance();
let j2 = e1.instance();
let jh = intf::spawn(async move {
assert_eq!(j1.await, 6);
assert_eq!(j2.await, 6);
});
intf::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 = intf::interval(1000, move || {
let tick = tick.clone();
async move {
let mut tick = tick.lock();
trace!("tick {}", tick);
*tick += 1;
}
});
intf::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!(
intf::timeout(2500, async move {
let mut tick = tick_1.lock();
trace!("tick {}", tick);
intf::sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
intf::sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
intf::sleep(1000).await;
*tick += 1;
trace!("tick {}", tick);
intf::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);
intf::sleep(1000).await;
assert!(sys_time.elapsed().unwrap() >= one_sec);
}
}
}
pub async fn test_protected_store() {
info!("testing protected store");
let _ = intf::remove_user_secret("test", "_test_key").await;
let _ = intf::remove_user_secret("test", "_test_broken").await;
let d1: [u8; 0] = [];
assert_eq!(
intf::save_user_secret("test", "_test_key", &[2u8, 3u8, 4u8]).await,
Ok(false)
);
info!("testing saving user secret");
assert_eq!(
intf::save_user_secret("test", "_test_key", &d1).await,
Ok(true)
);
info!("testing loading user secret");
assert_eq!(
intf::load_user_secret("test", "_test_key").await,
Ok(Some(d1.to_vec()))
);
info!("testing loading user secret again");
assert_eq!(
intf::load_user_secret("test", "_test_key").await,
Ok(Some(d1.to_vec()))
);
info!("testing loading broken user secret");
assert_eq!(
intf::load_user_secret("test", "_test_broken").await,
Ok(None)
);
info!("testing loading broken user secret again");
assert_eq!(
intf::load_user_secret("test", "_test_broken").await,
Ok(None)
);
info!("testing remove user secret");
assert_eq!(
intf::remove_user_secret("test", "_test_key").await,
Ok(true)
);
info!("testing remove user secret again");
assert_eq!(
intf::remove_user_secret("test", "_test_key").await,
Ok(false)
);
info!("testing remove broken user secret");
assert_eq!(
intf::remove_user_secret("test", "_test_broken").await,
Ok(false)
);
info!("testing remove broken user secret again");
assert_eq!(
intf::remove_user_secret("test", "_test_broken").await,
Ok(false)
);
let d2: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(
intf::save_user_secret("test", "_test_key", &[2u8, 3u8, 4u8]).await,
Ok(false)
);
assert_eq!(
intf::save_user_secret("test", "_test_key", &d2).await,
Ok(true)
);
assert_eq!(
intf::load_user_secret("test", "_test_key").await,
Ok(Some(d2.to_vec()))
);
assert_eq!(
intf::load_user_secret("test", "_test_key").await,
Ok(Some(d2.to_vec()))
);
assert_eq!(
intf::load_user_secret("test", "_test_broken").await,
Ok(None)
);
assert_eq!(
intf::load_user_secret("test", "_test_broken").await,
Ok(None)
);
assert_eq!(
intf::remove_user_secret("test", "_test_key").await,
Ok(true)
);
assert_eq!(
intf::remove_user_secret("test", "_test_key").await,
Ok(false)
);
assert_eq!(
intf::remove_user_secret("test", "_test_broken").await,
Ok(false)
);
assert_eq!(
intf::remove_user_secret("test", "_test_broken").await,
Ok(false)
);
let _ = intf::remove_user_secret("test", "_test_key").await;
let _ = intf::remove_user_secret("test", "_test_broken").await;
}
cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
pub async fn test_network_interfaces() {
info!("testing network interfaces");
let t1 = intf::get_timestamp();
let mut interfaces = intf::utils::network_interfaces::NetworkInterfaces::new();
let count = 100;
for _ in 0..count {
if let Err(e) = interfaces.refresh() {
error!("error refreshing interfaces: {}", e);
}
}
let t2 = intf::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_u64() {
info!("testing random number generator for u64");
let t1 = intf::get_timestamp();
let count = 10000;
for _ in 0..count {
let _ = intf::get_random_u64();
}
let t2 = intf::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 = intf::get_timestamp();
let count = 10000;
for _ in 0..count {
let _ = intf::get_random_u32();
}
let t2 = intf::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_single_future() {
info!("testing single future");
let sf = SingleFuture::<u32>::new();
assert_eq!(sf.check().await, Ok(None));
assert_eq!(
sf.single_spawn(async {
intf::sleep(2000).await;
69
})
.await,
Ok(None)
);
assert_eq!(sf.check().await, Ok(None));
assert_eq!(sf.single_spawn(async { panic!() }).await, Ok(None));
assert_eq!(sf.join().await, Ok(Some(69)));
assert_eq!(
sf.single_spawn(async {
intf::sleep(1000).await;
37
})
.await,
Ok(None)
);
intf::sleep(2000).await;
assert_eq!(
sf.single_spawn(async {
intf::sleep(1000).await;
27
})
.await,
Ok(Some(37))
);
intf::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_get_random_u64().await;
test_get_random_u32().await;
test_sleep().await;
#[cfg(not(target_arch = "wasm32"))]
test_network_interfaces().await;
test_single_future().await;
test_eventual().await;
test_eventual_value().await;
test_eventual_value_clone().await;
test_interval().await;
test_timeout().await;
test_protected_store().await;
}
@@ -0,0 +1,184 @@
use super::test_veilid_config::*;
use crate::dht::key;
use crate::intf::*;
use crate::xx::*;
use crate::*;
fn setup_veilid_core() -> VeilidCoreSetup {
VeilidCoreSetup {
state_change_callback: Arc::new(
move |change: VeilidStateChange| -> SystemPinBoxFuture<()> {
Box::pin(async move {
trace!("state_change_callback: {:?}", change);
})
},
),
config_callback: Arc::new(config_callback),
}
}
async fn startup(core: VeilidCore) -> VeilidAPI {
trace!("test_table_store: starting");
core.startup(setup_veilid_core())
.await
.expect("startup failed")
}
async fn shutdown(api: VeilidAPI) {
trace!("test_table_store: shutting down");
api.shutdown().await;
trace!("test_table_store: finished");
}
pub async fn test_delete_open_delete(ts: TableStore) {
trace!("test_delete_open_delete");
let _ = ts.delete("test");
let db = ts.open("test", 3).await.expect("should have opened");
assert!(
ts.delete("test").await.is_err(),
"should fail because file is opened"
);
drop(db);
assert!(
ts.delete("test").await.is_ok(),
"should succeed because file is closed"
);
let db = ts.open("test", 3).await.expect("should have opened");
assert!(
ts.delete("test").await.is_err(),
"should fail because file is opened"
);
drop(db);
let db = ts.open("test", 3).await.expect("should have opened");
assert!(
ts.delete("test").await.is_err(),
"should fail because file is opened"
);
drop(db);
assert!(
ts.delete("test").await.is_ok(),
"should succeed because file is closed"
);
}
pub async fn test_store_delete_load(ts: TableStore) {
trace!("test_store_delete_load");
let _ = ts.delete("test");
let db = ts.open("test", 3).await.expect("should have opened");
assert!(
ts.delete("test").await.is_err(),
"should fail because file is opened"
);
assert_eq!(
db.load(0, b"foo").await,
Ok(None),
"should not load missing key"
);
assert!(
db.store(1, b"foo", b"1234567890").await.is_ok(),
"should store new key"
);
assert_eq!(
db.load(0, b"foo").await,
Ok(None),
"should not load missing key"
);
assert_eq!(db.load(1, b"foo").await, Ok(Some(b"1234567890".to_vec())));
assert!(
db.store(1, b"bar", b"FNORD").await.is_ok(),
"should store new key"
);
assert!(
db.store(0, b"bar", b"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
.await
.is_ok(),
"should store new key"
);
assert!(
db.store(2, b"bar", b"FNORD").await.is_ok(),
"should store new key"
);
assert!(
db.store(2, b"baz", b"QWERTY").await.is_ok(),
"should store new key"
);
assert!(
db.store(2, b"bar", b"QWERTYUIOP").await.is_ok(),
"should store new key"
);
assert_eq!(db.load(1, b"bar").await, Ok(Some(b"FNORD".to_vec())));
assert_eq!(
db.load(0, b"bar").await,
Ok(Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec()))
);
assert_eq!(db.load(2, b"bar").await, Ok(Some(b"QWERTYUIOP".to_vec())));
assert_eq!(db.load(2, b"baz").await, Ok(Some(b"QWERTY".to_vec())));
assert_eq!(db.delete(1, b"bar").await, Ok(true));
assert_eq!(db.delete(1, b"bar").await, Ok(false));
assert!(
db.delete(4, b"bar").await.is_err(),
"can't delete from column that doesn't exist"
);
drop(db);
let db = ts.open("test", 3).await.expect("should have opened");
assert_eq!(db.load(1, b"bar").await, Ok(None));
assert_eq!(
db.load(0, b"bar").await,
Ok(Some(b"ABCDEFGHIJKLMNOPQRSTUVWXYZ".to_vec()))
);
assert_eq!(db.load(2, b"bar").await, Ok(Some(b"QWERTYUIOP".to_vec())));
assert_eq!(db.load(2, b"baz").await, Ok(Some(b"QWERTY".to_vec())));
}
pub async fn test_cbor(ts: TableStore) {
trace!("test_cbor");
let _ = ts.delete("test");
let db = ts.open("test", 3).await.expect("should have opened");
let (dht_key, _) = key::generate_secret();
assert!(db.store_cbor(0, b"asdf", &dht_key).await.is_ok());
assert_eq!(db.load_cbor::<key::DHTKey>(0, b"qwer").await, Ok(None));
let d = match db.load_cbor::<key::DHTKey>(0, b"asdf").await {
Ok(x) => x,
Err(e) => {
assert!(false, "couldn't decode cbor: {}", e);
return;
}
};
assert_eq!(d, Some(dht_key), "keys should be equal");
assert!(
db.store(1, b"foo", b"1234567890").await.is_ok(),
"should store new key"
);
assert!(
db.load_cbor::<key::DHTKey>(1, b"foo").await.is_err(),
"should fail to load cbor"
);
}
pub async fn test_all() {
let core = VeilidCore::new();
let api = startup(core.clone()).await;
let ts = core.table_store();
test_delete_open_delete(ts.clone()).await;
test_store_delete_load(ts.clone()).await;
test_cbor(ts.clone()).await;
let _ = ts.delete("test").await;
shutdown(api).await;
}
@@ -0,0 +1,307 @@
use crate::xx::*;
use crate::*;
cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
static CERTFILE: &str = r#"-----BEGIN CERTIFICATE-----
MIIDbzCCAlegAwIBAgIRALB/PvRpqN55Pk7L33NNsvcwDQYJKoZIhvcNAQELBQAw
FDESMBAGA1UEAwwJTm9jdGVtIENBMB4XDTIwMDkwODIxMDkwMFoXDTMwMDkwNjIx
MDkwMFowHDEaMBgGA1UEAwwRKi5ub2N0ZW0uaW50ZXJuYWwwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDRbAtA2dIlTPaQUN43/bdGi2wuDzCXk36TcfOr
YoxGsyJV6QpcIdmtrPN2WbkuDmA/G+0BUcQPvBfA/pFRHQElrzMhGR23Mp6IK7YR
pomUa1DQSJyMw/WM9V0+tidp5tJSeUCB+qKhLBrztD5XXjdhU6WA1J0y26XQoBqs
RZbPV8mce4LxVaQptkf4NB4/jnr3M1/FWEri60xBw3blWGaLP6gza3vqAr8pqEY4
zXU4q+egLbRIOwxwBJ0/vcyO6BdSzA1asWJCddXQJkUQrLl3OQ+44FMsAFyzCOiK
DVoqD2z4IJvIRT6TH8OcYvrotytlsNXS4ja9r32tTR1/DxUrAgMBAAGjgbMwgbAw
CQYDVR0TBAIwADAdBgNVHQ4EFgQUhjP4CArB3wWGHfavf7mRxaYshKMwRAYDVR0j
BD0wO4AUKAOv10AaiIUHgOtx0Mk6ZaZ/tGWhGKQWMBQxEjAQBgNVBAMMCU5vY3Rl
bSBDQYIJAISVWafozd3RMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIF
oDAcBgNVHREEFTATghEqLm5vY3RlbS5pbnRlcm5hbDANBgkqhkiG9w0BAQsFAAOC
AQEAMfVGtpXdkxflSQY2DzIUXLp9cZQnu4A8gww8iaLAg5CIUijP71tb2JJ+SsRx
W3p14YMhOYtswIvGTtXWzMgfAivwrxCcJefnqDAG9yviWoA0CSQe21nRjEqN6nyh
CS2BIkOcNNf10TD9sNo7z6IIXNjok7/F031JvH6pBgZ8Bq4IE/ANIuAvxwslPrqT
80qnWtAc5TzNNR1CT+fyZwMEpeW5fMZQnrSyUMsNv06Jydl/7IkGvlmbwihZOg95
Vty37pyzrXU5s/DY1zi5aYoFiK7/4bNEy9mRL9ero+kCvQfea0Yt2rITKQkCYvKu
MQTNaSyo6GTifW5InckkQIsnTQ==
-----END CERTIFICATE-----"#;
static KEYFILE: &str = r#"-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDRbAtA2dIlTPaQ
UN43/bdGi2wuDzCXk36TcfOrYoxGsyJV6QpcIdmtrPN2WbkuDmA/G+0BUcQPvBfA
/pFRHQElrzMhGR23Mp6IK7YRpomUa1DQSJyMw/WM9V0+tidp5tJSeUCB+qKhLBrz
tD5XXjdhU6WA1J0y26XQoBqsRZbPV8mce4LxVaQptkf4NB4/jnr3M1/FWEri60xB
w3blWGaLP6gza3vqAr8pqEY4zXU4q+egLbRIOwxwBJ0/vcyO6BdSzA1asWJCddXQ
JkUQrLl3OQ+44FMsAFyzCOiKDVoqD2z4IJvIRT6TH8OcYvrotytlsNXS4ja9r32t
TR1/DxUrAgMBAAECggEBAMIAK+CUqCbjyBliwKjvwWN5buqwKZyRBxXB3y/qJ/aq
pWkea/lzZjqMWDFP5sryiFiOHx00yMKmxP6FFMsmalSlm2DS6oM2QkP08kIhm5vB
WmjIizWfpo5BEnMwvQxOxpGeP5LpQtS5jfIrDAFVh0oC+fOBgmqFrXK5jlv+Tzmc
9PzoF5lgy8CHw3NxuScJpEhA1vTzu5N7sTdiTDKqY1ph2+RFlf30oyx4whoRVpIC
w8vp3WbLu/yAGuN5S14mYJW2Qgi8/rVCDStROEKOeB99mt1MG5lX7iuagzS/95Lr
2m1Nya0+7hkkpq6Y3Wqne9H0NLasJK8PU8ZaEc6BwTkCgYEA8iLVBrt4W/Cc5hry
8LWCMX8P25z7WIRYswnPvqwTwE0f6Q1ddWIaR9GPWUHgoRC4Z0b0MKolwo9s8RPE
GBuTOCy8ArSgYb1jNpsanGIWg6mZZgfylKdMdCMXMAAYF1/sTXeqCDY+FSCzEAvZ
hzppcCpiKV7Pa9aOo7o3/IeUBZcCgYEA3WmyvscG27R18XASJYL8Y4DuFvvnTHMp
YnxJIoS1+0TnUD2QqXUnXKbnTioWs7t990YAjbsHvK4fVsbnkuEm/as0oYbC8vU1
W3XN0HrpiacGcYIcXU4AY4XvY8t3y76FycJAT9Q6QztVofI5DmXV+8qsyrEegUys
wPIkkumCJ40CgYBKT3hTPZudk8WDNQgT6ZCQQi+Kta3Jp6xVHhC8srDJFqJRcsGY
8ceg/OZifT5EEA6X24W7naxC/qNvhSJsR6Ix3kDBD9AczvOw4X8UOWIxfA5Q6uV+
y61CAzbti0nZep3Z1HzBUmxRLZzmssxKnRmYy9keWzOLI+jYxKDEBpPd9wKBgAY1
pquvDUQwJXal+/xNViK8RPEkE3KTcD+w2KQ9MJVhc1NOxrXZ8Uap76bDi2tzAK9k
qTNQYYErKPnYDjqSUfOfT5SQIPuLYPm1rhYAvHf91TJtwbnkLCKeaP5VgICYUUw9
RGx4uUGVcmteTbdXp86t+naczQw3SEkJAXmVTu8pAoGATF7xXifMUSL1v43Ybrmc
RikQyDecRspMYLOCNmPWI2PPz6MAjm8jDCsXK52HUK4mUqrd/W3rqnl+TrJsXOnH
Ww6tESPaF1kCVyV2Jx/5m8qsE9y5Bds7eMo2JF8vnAKFX6t4KwZiyHBymj6uelNc
wFAbkZY9eS/x6P7qrpd7dUA=
-----END PRIVATE KEY-----"#;
}
}
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub fn get_tablestore_path() -> String {
String::new()
}
pub fn get_certfile_path() -> String {
String::new()
}
pub fn get_keyfile_path() -> String {
String::new()
}
}
else {
fn get_data_dir() -> PathBuf {
let out;
cfg_if! {
if #[cfg(target_os = "android")] {
out = PathBuf::from(intf::utils::android::get_files_dir());
} else {
use directories::*;
if let Some(my_proj_dirs) = ProjectDirs::from("org", "Veilid", "VeilidCoreTests") {
out = PathBuf::from(my_proj_dirs.data_local_dir());
} else {
out = PathBuf::from("./");
}
}
}
out
}
pub fn get_tablestore_path() -> String {
let mut out = get_data_dir();
std::fs::create_dir_all(&out).unwrap();
out.push("tablestore");
out.into_os_string().into_string().unwrap()
}
pub fn get_certfile_path() -> String {
let mut out = get_data_dir();
std::fs::create_dir_all(&out).unwrap();
out.push("cert.pem");
// Initialize certfile
if !out.exists() {
debug!("creating certfile at {:?}", out);
File::create(&out).unwrap().write_all(CERTFILE.as_bytes()).unwrap();
}
out.into_os_string().into_string().unwrap()
}
pub fn get_keyfile_path() -> String {
let mut out = get_data_dir();
std::fs::create_dir_all(&out).unwrap();
out.push("key.pem");
// Initialize keyfile
if !out.exists() {
debug!("creating keyfile at {:?}", out);
File::create(&out).unwrap().write_all(KEYFILE.as_bytes()).unwrap();
}
out.into_os_string().into_string().unwrap()
}
}
}
pub fn setup_veilid_core() -> VeilidCoreSetup {
VeilidCoreSetup {
state_change_callback: Arc::new(
move |change: VeilidStateChange| -> SystemPinBoxFuture<()> {
Box::pin(async move {
trace!("state_change_callback: {:?}", change);
})
},
),
config_callback: Arc::new(config_callback),
}
}
pub fn config_callback(key: String) -> Result<Box<dyn core::any::Any>, String> {
match key.as_str() {
"namespace" => Ok(Box::new(String::from(""))),
"capabilities.protocol_udp" => Ok(Box::new(true)),
"capabilities.protocol_connect_tcp" => Ok(Box::new(true)),
"capabilities.protocol_accept_tcp" => Ok(Box::new(true)),
"capabilities.protocol_connect_ws" => Ok(Box::new(true)),
"capabilities.protocol_accept_ws" => Ok(Box::new(true)),
"capabilities.protocol_connect_wss" => Ok(Box::new(true)),
"capabilities.protocol_accept_wss" => Ok(Box::new(true)),
"tablestore.directory" => Ok(Box::new(get_tablestore_path())),
"network.max_connections" => Ok(Box::new(16u32)),
"network.connection_initial_timeout" => Ok(Box::new(2_000_000u64)),
"network.node_id" => Ok(Box::new(dht::key::DHTKey::default())),
"network.node_id_secret" => Ok(Box::new(dht::key::DHTKeySecret::default())),
"network.bootstrap" => Ok(Box::new(vec![String::from("asdf"), String::from("qwer")])),
"network.rpc.concurrency" => Ok(Box::new(2u32)),
"network.rpc.queue_size" => Ok(Box::new(128u32)),
"network.rpc.max_timestamp_behind" => Ok(Box::new(Some(10_000_000u64))),
"network.rpc.max_timestamp_ahead" => Ok(Box::new(Some(10_000_000u64))),
"network.rpc.timeout" => Ok(Box::new(10_000_000u64)),
"network.rpc.max_route_hop_count" => Ok(Box::new(7u8)),
"network.dht.resolve_node_timeout" => Ok(Box::new(Option::<u64>::None)),
"network.dht.resolve_node_count" => Ok(Box::new(20u32)),
"network.dht.resolve_node_fanout" => Ok(Box::new(3u32)),
"network.dht.max_find_node_count" => Ok(Box::new(20u32)),
"network.dht.get_value_timeout" => Ok(Box::new(Option::<u64>::None)),
"network.dht.get_value_count" => Ok(Box::new(20u32)),
"network.dht.get_value_fanout" => Ok(Box::new(3u32)),
"network.dht.set_value_timeout" => Ok(Box::new(Option::<u64>::None)),
"network.dht.set_value_count" => Ok(Box::new(20u32)),
"network.dht.set_value_fanout" => Ok(Box::new(5u32)),
"network.dht.min_peer_count" => Ok(Box::new(20u32)),
"network.dht.min_peer_refresh_time" => Ok(Box::new(2000000u64)),
"network.dht.validate_dial_info_receipt_time" => Ok(Box::new(5000000u64)),
"network.upnp" => Ok(Box::new(false)),
"network.natpmp" => Ok(Box::new(false)),
"network.address_filter" => Ok(Box::new(true)),
"network.tls.certificate_path" => Ok(Box::new(get_certfile_path())),
"network.tls.private_key_path" => Ok(Box::new(get_keyfile_path())),
"network.tls.connection_initial_timeout" => Ok(Box::new(2_000_000u64)),
"network.application.path" => Ok(Box::new(String::from("/app"))),
"network.application.https.enabled" => Ok(Box::new(true)),
"network.application.https.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.application.http.enabled" => Ok(Box::new(true)),
"network.application.http.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.protocol.udp.enabled" => Ok(Box::new(true)),
"network.protocol.udp.socket_pool_size" => Ok(Box::new(0u32)),
"network.protocol.udp.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.protocol.udp.public_address" => Ok(Box::new(Option::<String>::None)),
"network.protocol.tcp.connect" => Ok(Box::new(true)),
"network.protocol.tcp.listen" => Ok(Box::new(true)),
"network.protocol.tcp.max_connections" => Ok(Box::new(32u32)),
"network.protocol.tcp.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.protocol.tcp.public_address" => Ok(Box::new(Option::<String>::None)),
"network.protocol.ws.connect" => Ok(Box::new(true)),
"network.protocol.ws.listen" => Ok(Box::new(true)),
"network.protocol.ws.max_connections" => Ok(Box::new(16u32)),
"network.protocol.ws.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.protocol.ws.path" => Ok(Box::new(String::from("/ws"))),
"network.protocol.ws.public_address" => Ok(Box::new(Option::<String>::None)),
"network.protocol.wss.connect" => Ok(Box::new(true)),
"network.protocol.wss.listen" => Ok(Box::new(true)),
"network.protocol.wss.max_connections" => Ok(Box::new(16u32)),
"network.protocol.wss.listen_address" => Ok(Box::new(String::from("[::1]:5150"))),
"network.protocol.wss.path" => Ok(Box::new(String::from("/ws"))),
"network.protocol.wss.public_address" => Ok(Box::new(Option::<String>::None)),
"network.leases.max_server_signal_leases" => Ok(Box::new(256u32)),
"network.leases.max_server_relay_leases" => Ok(Box::new(8u32)),
"network.leases.max_client_signal_leases" => Ok(Box::new(2u32)),
"network.leases.max_client_relay_leases" => Ok(Box::new(2u32)),
_ => Err(format!("config key '{}' doesn't exist", key)),
}
}
pub async fn test_config() {
let mut vc = VeilidConfig::new();
match vc.init(Arc::new(config_callback)).await {
Ok(()) => (),
Err(e) => {
error!("Error: {}", e);
assert!(false);
}
}
let inner = vc.get();
assert_eq!(inner.namespace, String::from(""));
assert_eq!(inner.capabilities.protocol_udp, true);
assert_eq!(inner.capabilities.protocol_connect_tcp, true);
assert_eq!(inner.capabilities.protocol_accept_tcp, true);
assert_eq!(inner.capabilities.protocol_connect_ws, true);
assert_eq!(inner.capabilities.protocol_accept_ws, true);
assert_eq!(inner.capabilities.protocol_connect_wss, true);
assert_eq!(inner.capabilities.protocol_accept_wss, true);
assert_eq!(inner.tablestore.directory, get_tablestore_path());
assert_eq!(inner.network.max_connections, 16);
assert_eq!(inner.network.connection_initial_timeout, 2_000_000u64);
assert!(inner.network.node_id.valid);
assert!(inner.network.node_id_secret.valid);
assert_eq!(
inner.network.bootstrap,
vec![String::from("asdf"), String::from("qwer")]
);
assert_eq!(inner.network.rpc.concurrency, 2u32);
assert_eq!(inner.network.rpc.queue_size, 128u32);
assert_eq!(inner.network.rpc.timeout, 10_000_000u64);
assert_eq!(inner.network.rpc.max_route_hop_count, 7u8);
assert_eq!(inner.network.dht.resolve_node_timeout, Option::<u64>::None);
assert_eq!(inner.network.dht.resolve_node_count, 20u32);
assert_eq!(inner.network.dht.resolve_node_fanout, 3u32);
assert_eq!(inner.network.dht.get_value_timeout, Option::<u64>::None);
assert_eq!(inner.network.dht.get_value_count, 20u32);
assert_eq!(inner.network.dht.get_value_fanout, 3u32);
assert_eq!(inner.network.dht.set_value_timeout, Option::<u64>::None);
assert_eq!(inner.network.dht.set_value_count, 20u32);
assert_eq!(inner.network.dht.set_value_fanout, 5u32);
assert_eq!(inner.network.dht.min_peer_count, 20u32);
assert_eq!(inner.network.dht.min_peer_refresh_time, 2000000u64);
assert_eq!(
inner.network.dht.validate_dial_info_receipt_time,
5000000u64
);
assert_eq!(inner.network.upnp, false);
assert_eq!(inner.network.natpmp, false);
assert_eq!(inner.network.address_filter, true);
assert_eq!(inner.network.tls.certificate_path, get_certfile_path());
assert_eq!(inner.network.tls.private_key_path, get_keyfile_path());
assert_eq!(inner.network.tls.connection_initial_timeout, 2_000_000u64);
assert_eq!(inner.network.application.path, "/app");
assert_eq!(inner.network.application.https.enabled, true);
assert_eq!(inner.network.application.https.listen_address, "[::1]:5150");
assert_eq!(inner.network.application.http.enabled, true);
assert_eq!(inner.network.application.http.listen_address, "[::1]:5150");
assert_eq!(inner.network.protocol.udp.enabled, true);
assert_eq!(inner.network.protocol.udp.socket_pool_size, 0u32);
assert_eq!(inner.network.protocol.udp.listen_address, "[::1]:5150");
assert_eq!(inner.network.protocol.udp.public_address, None);
assert_eq!(inner.network.protocol.tcp.connect, true);
assert_eq!(inner.network.protocol.tcp.listen, true);
assert_eq!(inner.network.protocol.tcp.max_connections, 32u32);
assert_eq!(inner.network.protocol.tcp.listen_address, "[::1]:5150");
assert_eq!(inner.network.protocol.tcp.public_address, None);
assert_eq!(inner.network.protocol.ws.connect, true);
assert_eq!(inner.network.protocol.ws.listen, true);
assert_eq!(inner.network.protocol.ws.max_connections, 16u32);
assert_eq!(inner.network.protocol.ws.listen_address, "[::1]:5150");
assert_eq!(inner.network.protocol.ws.path, "/ws");
assert_eq!(inner.network.protocol.ws.public_address, None);
assert_eq!(inner.network.protocol.wss.connect, true);
assert_eq!(inner.network.protocol.wss.listen, true);
assert_eq!(inner.network.protocol.wss.max_connections, 16u32);
assert_eq!(inner.network.protocol.wss.listen_address, "[::1]:5150");
assert_eq!(inner.network.protocol.wss.path, "/ws");
assert_eq!(inner.network.protocol.wss.public_address, None);
}
pub async fn test_all() {
test_config().await;
}
@@ -0,0 +1,53 @@
use super::test_veilid_config::*;
use crate::xx::*;
use crate::*;
pub async fn test_startup_shutdown() {
trace!("test_startup_shutdown: starting");
let veilid_core = VeilidCore::new();
let api = veilid_core
.startup(setup_veilid_core())
.await
.expect("startup failed");
trace!("test_startup_shutdown: shutting down");
api.shutdown().await;
trace!("test_startup_shutdown: finished");
}
pub async fn test_attach_detach() {
let veilid_core = VeilidCore::new();
info!("--- test normal order ---");
let api = veilid_core
.startup(setup_veilid_core())
.await
.expect("startup failed");
api.attach().await;
intf::sleep(5000).await;
api.detach().await;
api.wait_for_state(VeilidState::Attachment(AttachmentState::Detached))
.await;
api.shutdown().await;
info!("--- test auto detach ---");
let api = veilid_core
.startup(setup_veilid_core())
.await
.expect("startup failed");
api.attach().await;
intf::sleep(5000).await;
api.shutdown().await;
info!("--- test detach without attach ---");
let api = veilid_core
.startup(setup_veilid_core())
.await
.expect("startup failed");
api.detach().await;
api.shutdown().await;
}
pub async fn test_all() {
test_startup_shutdown().await;
test_attach_detach().await;
}
+88
View File
@@ -0,0 +1,88 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
12:ce:63:bd:90:f5:ab:de:6d:7f:d7:3e:f3:e6:bb
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Veilid Test CA
Validity
Not Before: Nov 22 13:52:16 2021 GMT
Not After : Feb 25 13:52:16 2024 GMT
Subject: CN=Veilid Test Certificate
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:cb:2e:7a:47:81:be:6f:6b:53:37:51:c1:50:68:
5a:44:3d:ba:b9:9b:78:40:84:35:d4:0e:e8:41:a6:
0e:0a:b9:34:ae:97:a3:37:3e:81:ed:6c:0f:f8:8a:
8b:0b:1a:ed:06:97:57:6d:49:a5:ec:b4:c4:d8:6d:
d2:57:c3:87:89:99:ee:b0:d7:c5:82:a1:dc:d5:98:
b3:ef:10:da:c0:5c:38:a2:bb:15:3e:0e:5e:bc:a0:
cd:a1:f0:07:67:bb:57:3f:89:cc:72:4f:bb:c0:a7:
ed:ad:15:07:61:c2:b4:21:73:39:00:9b:8f:aa:04:
1b:c4:9d:d4:00:44:87:b1:79:b4:e1:4e:01:3c:ee:
a4:bb:f9:ad:5d:88:41:03:b4:bf:df:bf:71:24:ee:
0b:69:59:55:dd:43:d1:91:04:de:98:9c:54:f2:ee:
63:78:fe:76:19:bf:e6:5d:d6:58:81:3c:1b:02:3d:
5d:cc:70:4a:c1:84:06:f6:1a:db:16:b0:e0:30:b0:
3a:85:41:48:a1:88:c5:38:04:7b:03:c4:86:f0:da:
1a:ff:bc:d1:ac:7f:cd:0c:e8:5a:42:5e:43:7f:0d:
61:5d:41:67:0f:b8:07:47:21:93:44:b2:ab:fa:d8:
69:bb:b9:6d:a1:56:6d:23:54:aa:49:67:e7:57:c6:
e9:c7
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
70:ED:B0:96:71:33:43:16:EF:32:FF:69:11:C9:F0:02:3F:6C:81:88
X509v3 Authority Key Identifier:
keyid:5D:7F:8D:AF:1A:56:D3:F4:CA:3D:D3:6D:EF:50:11:F7:64:99:6F:02
DirName:/CN=Veilid Test CA
serial:22:7A:2E:68:7C:DF:7B:81:85:1A:50:98:16:62:22:D0:0B:D6:1C:4A
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:Veilid Test Certificate
Signature Algorithm: sha256WithRSAEncryption
b8:fc:ac:62:d6:95:af:09:db:24:7d:82:2c:02:e1:d0:7b:f5:
69:03:a4:42:55:c6:0d:2a:f1:9d:0e:c4:9b:78:40:7d:0d:7d:
ec:66:f6:c4:6d:06:d0:5b:58:de:ba:e6:67:ea:af:41:a3:87:
b4:37:8b:a8:1f:51:ae:70:e0:0d:f5:51:0a:7a:b3:b3:1d:d1:
77:92:63:35:ae:50:9e:04:3d:04:6e:f1:60:c8:e3:8f:1f:75:
47:05:27:a0:ff:c5:1b:30:68:b2:f9:5b:e6:f2:81:0f:9b:f2:
e8:8c:9d:b6:57:b2:c1:29:e7:d0:d0:88:b3:ba:8e:78:2e:ef:
ce:03:a3:12:fa:b4:e9:4e:1f:de:1a:cb:77:72:6b:71:98:02:
37:d2:b4:02:f0:2c:08:67:ca:75:0d:af:81:bf:f8:57:f8:d9:
4a:93:4f:db:3c:e1:af:3e:ab:9c:fe:87:f0:3a:01:21:6a:5c:
99:83:e3:03:47:98:15:23:24:b3:ee:29:27:f4:f1:34:c1:e4:
f8:39:5a:92:da:c7:08:dc:71:87:1c:ff:67:e7:ef:24:bc:34:
e3:4e:e0:16:12:84:60:d4:7f:a2:c0:5b:85:a9:c5:ef:78:0b:
c3:64:cb:b4:05:eb:51:e5:c1:0f:60:da:5c:98:08:bf:5d:b9:
1d:33:a7:26
-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIPEs5jvZD1q95tf9c+8+a7MA0GCSqGSIb3DQEBCwUAMBkx
FzAVBgNVBAMMDlZlaWxpZCBUZXN0IENBMB4XDTIxMTEyMjEzNTIxNloXDTI0MDIy
NTEzNTIxNlowIjEgMB4GA1UEAwwXVmVpbGlkIFRlc3QgQ2VydGlmaWNhdGUwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLLnpHgb5va1M3UcFQaFpEPbq5
m3hAhDXUDuhBpg4KuTSul6M3PoHtbA/4iosLGu0Gl1dtSaXstMTYbdJXw4eJme6w
18WCodzVmLPvENrAXDiiuxU+Dl68oM2h8Adnu1c/icxyT7vAp+2tFQdhwrQhczkA
m4+qBBvEndQARIexebThTgE87qS7+a1diEEDtL/fv3Ek7gtpWVXdQ9GRBN6YnFTy
7mN4/nYZv+Zd1liBPBsCPV3McErBhAb2GtsWsOAwsDqFQUihiMU4BHsDxIbw2hr/
vNGsf80M6FpCXkN/DWFdQWcPuAdHIZNEsqv62Gm7uW2hVm0jVKpJZ+dXxunHAgMB
AAGjgckwgcYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUcO2wlnEzQxbvMv9pEcnwAj9s
gYgwVAYDVR0jBE0wS4AUXX+NrxpW0/TKPdNt71AR92SZbwKhHaQbMBkxFzAVBgNV
BAMMDlZlaWxpZCBUZXN0IENBghQiei5ofN97gYUaUJgWYiLQC9YcSjATBgNVHSUE
DDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwIgYDVR0RBBswGYIXVmVpbGlkIFRl
c3QgQ2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggEBALj8rGLWla8J2yR9giwC
4dB79WkDpEJVxg0q8Z0OxJt4QH0Nfexm9sRtBtBbWN665mfqr0Gjh7Q3i6gfUa5w
4A31UQp6s7Md0XeSYzWuUJ4EPQRu8WDI448fdUcFJ6D/xRswaLL5W+bygQ+b8uiM
nbZXssEp59DQiLO6jngu784DoxL6tOlOH94ay3dya3GYAjfStALwLAhnynUNr4G/
+Ff42UqTT9s84a8+q5z+h/A6ASFqXJmD4wNHmBUjJLPuKSf08TTB5Pg5WpLaxwjc
cYcc/2fn7yS8NONO4BYShGDUf6LAW4Wpxe94C8Nky7QF61HlwQ9g2lyYCL9duR0z
pyY=
-----END CERTIFICATE-----
+27
View File
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyy56R4G+b2tTN1HBUGhaRD26uZt4QIQ11A7oQaYOCrk0rpej
Nz6B7WwP+IqLCxrtBpdXbUml7LTE2G3SV8OHiZnusNfFgqHc1Ziz7xDawFw4orsV
Pg5evKDNofAHZ7tXP4nMck+7wKftrRUHYcK0IXM5AJuPqgQbxJ3UAESHsXm04U4B
PO6ku/mtXYhBA7S/379xJO4LaVlV3UPRkQTemJxU8u5jeP52Gb/mXdZYgTwbAj1d
zHBKwYQG9hrbFrDgMLA6hUFIoYjFOAR7A8SG8Noa/7zRrH/NDOhaQl5Dfw1hXUFn
D7gHRyGTRLKr+thpu7ltoVZtI1SqSWfnV8bpxwIDAQABAoIBAQCae5MjbUWC56JU
7EdEQKNpQVoIp2mt/BgFTPRQfdYtVxX0LX0+krss7r3R5lzDq8xN96HUiWur5uHI
APAuJI+YEr8GHHii0zjZ+onMmg8ItNWm/QGwtjJXzxeqKZsnxqwWtkoJHBCP8d5n
fBapwOU+jaHokV6RESCfxLSdI33cdGcOgDAn4/lvcXZ4Pq0qbitFuZwBPpobHbp4
Mo94K7oh4KCt3FDMfZshkSF0wlquRIeUsI2uZUofybDa/j1RgEsqBZIrHqM6xXV1
/r13+mMZC4otE0qhBV9jTYffaxooOnae8/Ve0FgaPWpNm7AD6p7l4a3csIkcggMS
xx7cntR5AoGBAOvPgDDLJ7h+AgY7jAd13/eZ75NtuEWbSq4c4Kwwy1K17L+3isX/
RRkQ5qGTNsT6j1dddfwzX6Rhsi+JywczEdJdWgGNpFCIa8Ly2+47YLDpv0ZIISIZ
V0Ngg6dyuuQo7gFlLz9Dhe/If32/93gEW6HZOjn+GmQu53ZSDdHvukpjAoGBANyT
0GZzaP2ulV3Pk+9nJhC6eK2BZWF4ODXHsAgNUEyWZ4qDM71oDxyFbaWS2IDg7jz7
T2wVffRFDcx8oNXWbhWbejSBGHWI8HRk0Ki83K0r7Cj8Uhy53rQjGOsdLf3K9T9h
GGVcwMHlBGIvswqTnJKysvgcoh1Ir+6RqbfCmG5NAoGAaVa8UQ+vor7HcLlRCFQj
xJvDZfxxgMaqSbUkuEbjzQLvy4TWPTSXTWc7X5o/sSasub5KYmsgonHyA0Juq7yo
jWyeNGttp3wJh4CttnJX8y+3/lFiW7UuQi7vIPIjgqC2EXF99ajYQBE0wpvqlHZ9
6IL9e8KDT5WUWEq3WbzZXzkCgYB/0Md6FnZISdoTui0nFMZh+yvinpB4ookv4L6I
a+6T8rOc99oLbzkSdd7LiwQZ6j0i6R1krC+IVFtimvU39EFmE+oEcqoRsYBkcebX
YFkfn8wBE/Ug4DPEfnH6C7aS0gC68TCJy+2GbYbUvn8pKdAY0aQTUcQ+49fOjmmi
KgjaIQKBgQDoT0af/7a7LnY9dkbkz624HmNVyMPOa4/STrdxyy3NRhq/dysRW+At
x30nvCWpv0Z5BAyaUCrRWPGFxhv3/Z7qb4fx5uUbC3Jc04I5D6fwYqrQofGS8TMK
Lrg83o5Ag++pllu1IeWiGQPRbn7VZ+O6pISgpRpYBexXGyLJ6wtcAw==
-----END RSA PRIVATE KEY-----
+91
View File
@@ -0,0 +1,91 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
## Obj-C/Swift specific
*.hmap
## App packaging
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build/
# Accio dependency management
Dependencies/
.accio/
# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
@@ -0,0 +1,8 @@
//
// veilidcore.c
// veilidcore-tests
//
// Created by JSmith on 7/6/21.
//
#include "veilid-core.h"
@@ -0,0 +1,13 @@
//
// veilid-core.h
// veilid-core-tests
//
// Created by JSmith on 7/6/21.
//
#ifndef veilid_core_h
#define veilid_core_h
void run_veilid_core_tests(void);
#endif /* veilid-core_h */
@@ -0,0 +1,5 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#include "veilid-core.h"
@@ -0,0 +1,413 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
4317C6BD2694A676009C717F /* veilid-core.c in Sources */ = {isa = PBXBuildFile; fileRef = 4317C6BC2694A676009C717F /* veilid-core.c */; };
43C436B0268904AC002D11C5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C436AF268904AC002D11C5 /* AppDelegate.swift */; };
43C436B2268904AC002D11C5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C436B1268904AC002D11C5 /* SceneDelegate.swift */; };
43C436B4268904AC002D11C5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C436B3268904AC002D11C5 /* ViewController.swift */; };
43C436B7268904AC002D11C5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43C436B5268904AC002D11C5 /* Main.storyboard */; };
43C436B9268904AD002D11C5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43C436B8268904AD002D11C5 /* Assets.xcassets */; };
43C436BC268904AD002D11C5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43C436BA268904AD002D11C5 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
4317C6BA2694A675009C717F /* veilidcore-tests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "veilidcore-tests-Bridging-Header.h"; sourceTree = "<group>"; };
4317C6BB2694A676009C717F /* veilid-core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = veilid-core.h; sourceTree = "<group>"; };
4317C6BC2694A676009C717F /* veilid-core.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = veilid-core.c; sourceTree = "<group>"; };
43C436AC268904AC002D11C5 /* veilidcore-tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "veilidcore-tests.app"; sourceTree = BUILT_PRODUCTS_DIR; };
43C436AF268904AC002D11C5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
43C436B1268904AC002D11C5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
43C436B3268904AC002D11C5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
43C436B6268904AC002D11C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
43C436B8268904AD002D11C5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
43C436BB268904AD002D11C5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
43C436BD268904AD002D11C5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
43C436A9268904AC002D11C5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4317C6B7269490DA009C717F /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
43C436A3268904AC002D11C5 = {
isa = PBXGroup;
children = (
4317C6BB2694A676009C717F /* veilid-core.h */,
4317C6BC2694A676009C717F /* veilid-core.c */,
43C436AE268904AC002D11C5 /* veilidcore-tests */,
43C436AD268904AC002D11C5 /* Products */,
4317C6B7269490DA009C717F /* Frameworks */,
4317C6BA2694A675009C717F /* veilidcore-tests-Bridging-Header.h */,
);
sourceTree = "<group>";
};
43C436AD268904AC002D11C5 /* Products */ = {
isa = PBXGroup;
children = (
43C436AC268904AC002D11C5 /* veilidcore-tests.app */,
);
name = Products;
sourceTree = "<group>";
};
43C436AE268904AC002D11C5 /* veilidcore-tests */ = {
isa = PBXGroup;
children = (
43C436AF268904AC002D11C5 /* AppDelegate.swift */,
43C436B1268904AC002D11C5 /* SceneDelegate.swift */,
43C436B3268904AC002D11C5 /* ViewController.swift */,
43C436B5268904AC002D11C5 /* Main.storyboard */,
43C436B8268904AD002D11C5 /* Assets.xcassets */,
43C436BA268904AD002D11C5 /* LaunchScreen.storyboard */,
43C436BD268904AD002D11C5 /* Info.plist */,
);
path = "veilidcore-tests";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
43C436AB268904AC002D11C5 /* veilidcore-tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 43C436C0268904AD002D11C5 /* Build configuration list for PBXNativeTarget "veilidcore-tests" */;
buildPhases = (
43C436C326893020002D11C5 /* Cargo Build */,
43C436A8268904AC002D11C5 /* Sources */,
43C436A9268904AC002D11C5 /* Frameworks */,
43C436AA268904AC002D11C5 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "veilidcore-tests";
productName = "veilidcore-tests";
productReference = 43C436AC268904AC002D11C5 /* veilidcore-tests.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
43C436A4268904AC002D11C5 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1250;
LastUpgradeCheck = 1250;
TargetAttributes = {
43C436AB268904AC002D11C5 = {
CreatedOnToolsVersion = 12.5.1;
LastSwiftMigration = 1250;
};
};
};
buildConfigurationList = 43C436A7268904AC002D11C5 /* Build configuration list for PBXProject "veilidcore-tests" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 43C436A3268904AC002D11C5;
productRefGroup = 43C436AD268904AC002D11C5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
43C436AB268904AC002D11C5 /* veilidcore-tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
43C436AA268904AC002D11C5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
43C436BC268904AD002D11C5 /* LaunchScreen.storyboard in Resources */,
43C436B9268904AD002D11C5 /* Assets.xcassets in Resources */,
43C436B7268904AC002D11C5 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
43C436C326893020002D11C5 /* Cargo Build */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Cargo Build";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "../../../../ios_build.sh --features ios_tests\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
43C436A8268904AC002D11C5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
43C436B4268904AC002D11C5 /* ViewController.swift in Sources */,
43C436B0268904AC002D11C5 /* AppDelegate.swift in Sources */,
43C436B2268904AC002D11C5 /* SceneDelegate.swift in Sources */,
4317C6BD2694A676009C717F /* veilid-core.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
43C436B5268904AC002D11C5 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
43C436B6268904AC002D11C5 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
43C436BA268904AD002D11C5 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
43C436BB268904AD002D11C5 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
43C436BE268904AD002D11C5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = arm64;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
43C436BF268904AD002D11C5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = arm64;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
43C436C1268904AD002D11C5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = ZJPQSFX5MW;
INFOPLIST_FILE = "veilidcore-tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.3;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-L../../../../target/aarch64-apple-ios/debug",
"-lveilid_core",
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-L../../../../target/x86_64-apple-ios/debug",
"-lveilid_core",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.veilid.veilidcore-tests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "veilidcore-tests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
43C436C2268904AD002D11C5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = ZJPQSFX5MW;
INFOPLIST_FILE = "veilidcore-tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.3;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-L../../../../target/aarch64-apple-ios/release",
"-lveilid_core",
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-L../../../../target/x86_64-apple-ios/release",
"-lveilid_core",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.veilid.veilidcore-tests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "veilidcore-tests-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
43C436A7268904AC002D11C5 /* Build configuration list for PBXProject "veilidcore-tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
43C436BE268904AD002D11C5 /* Debug */,
43C436BF268904AD002D11C5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
43C436C0268904AD002D11C5 /* Build configuration list for PBXNativeTarget "veilidcore-tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
43C436C1268904AD002D11C5 /* Debug */,
43C436C2268904AD002D11C5 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 43C436A4268904AC002D11C5 /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1250"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43C436AB268904AC002D11C5"
BuildableName = "veilidcore-tests.app"
BlueprintName = "veilidcore-tests"
ReferencedContainer = "container:veilidcore-tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43C436AB268904AC002D11C5"
BuildableName = "veilidcore-tests.app"
BlueprintName = "veilidcore-tests"
ReferencedContainer = "container:veilidcore-tests.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43C436AB268904AC002D11C5"
BuildableName = "veilidcore-tests.app"
BlueprintName = "veilidcore-tests"
ReferencedContainer = "container:veilidcore-tests.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,37 @@
//
// AppDelegate.swift
// veilidcore-tests
//
// Created by JSmith on 6/27/21.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_5" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillProportionally" translatesAutoresizingMaskIntoConstraints="NO" id="mVq-tL-Ygy">
<rect key="frame" x="0.0" y="44" width="414" height="818"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="VeilidCore Tests" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i8k-KY-R3P">
<rect key="frame" x="0.0" y="0.0" width="414" height="818"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="i8k-KY-R3P" firstAttribute="centerY" secondItem="mVq-tL-Ygy" secondAttribute="centerY" id="Df4-l3-obA"/>
<constraint firstItem="i8k-KY-R3P" firstAttribute="centerX" secondItem="mVq-tL-Ygy" secondAttribute="centerX" id="N20-xf-BCW"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="mVq-tL-Ygy" secondAttribute="bottom" id="Yv5-u7-OoL"/>
<constraint firstItem="mVq-tL-Ygy" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="gak-4I-MXo"/>
<constraint firstItem="mVq-tL-Ygy" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="khR-o9-jgW"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="mVq-tL-Ygy" secondAttribute="trailing" id="uvM-zO-INi"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="52.173913043478265" y="375"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="veilidcore_tests" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillProportionally" translatesAutoresizingMaskIntoConstraints="NO" id="p3h-g8-PO1">
<rect key="frame" x="0.0" y="44" width="414" height="818"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="VeilidCore Tests" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a8c-TH-kqT">
<rect key="frame" x="0.0" y="0.0" width="414" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="xHB-Zh-2dq">
<rect key="frame" x="0.0" y="20.5" width="414" height="797.5"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<mutableString key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, 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. Nam liber te conscient to factor tum poen legum odioque civiuda.</mutableString>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<constraints>
<constraint firstItem="a8c-TH-kqT" firstAttribute="leading" secondItem="p3h-g8-PO1" secondAttribute="leading" id="2A8-tP-OIK"/>
<constraint firstAttribute="trailing" secondItem="xHB-Zh-2dq" secondAttribute="trailing" id="2qF-CC-quW"/>
<constraint firstItem="a8c-TH-kqT" firstAttribute="centerX" secondItem="p3h-g8-PO1" secondAttribute="centerX" id="FZd-EA-ru3"/>
<constraint firstAttribute="trailing" secondItem="a8c-TH-kqT" secondAttribute="trailing" id="MuU-8i-2oK"/>
<constraint firstItem="xHB-Zh-2dq" firstAttribute="leading" secondItem="p3h-g8-PO1" secondAttribute="leading" id="iEU-k5-fyj"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="p3h-g8-PO1" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="1ir-0r-JXL"/>
<constraint firstItem="p3h-g8-PO1" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="A7D-oK-dVn"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="p3h-g8-PO1" secondAttribute="trailing" id="BaV-BF-LFn"/>
<constraint firstItem="p3h-g8-PO1" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="Xvj-L8-OZX"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="139" y="139"/>
</scene>
</scenes>
<resources>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,53 @@
//
// SceneDelegate.swift
// veilidcore-tests
//
// Created by JSmith on 6/27/21.
//
import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
@@ -0,0 +1,19 @@
//
// ViewController.swift
// veilidcore-tests
//
// Created by JSmith on 6/27/21.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
run_veilidcore_tests()
}
}
+3
View File
@@ -0,0 +1,3 @@
pub mod common;
#[cfg(not(target_arch = "wasm32"))]
mod native;
+195
View File
@@ -0,0 +1,195 @@
//! Test suite for Native
#![cfg(not(target_arch = "wasm32"))]
mod test_async_peek_stream;
use crate::tests::common::*;
use crate::xx::*;
#[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);
run_all_tests();
}
#[cfg(all(target_os = "ios", feature = "ios_tests"))]
#[no_mangle]
pub extern "C" fn run_veilid_core_tests() {
let log_path: std::path::PathBuf = [
std::env::var("HOME").unwrap().as_str(),
"Documents",
"veilid-core.log",
]
.iter()
.collect();
crate::intf::utils::ios::veilid_core_setup_ios(
"veilid-core",
Some(Level::Trace),
Some((Level::Trace, log_path.as_path())),
);
run_all_tests();
}
///////////////////////////////////////////////////////////////////////////
#[allow(dead_code)]
pub fn run_all_tests() {
info!("TEST: exec_test_host_interface");
exec_test_host_interface();
info!("TEST: exec_test_dht_key");
exec_test_dht_key();
info!("TEST: exec_test_veilid_core");
exec_test_veilid_core();
info!("TEST: exec_test_veilid_config");
exec_test_veilid_config();
info!("TEST: exec_test_async_peek_stream");
exec_test_async_peek_stream();
info!("TEST: exec_test_connection_table");
exec_test_connection_table();
info!("TEST: exec_test_table_store");
exec_test_table_store();
info!("TEST: exec_test_crypto");
exec_test_crypto();
info!("TEST: exec_test_envelope_receipt");
exec_test_envelope_receipt();
info!("Finished unit tests");
}
fn exec_test_host_interface() {
async_std::task::block_on(async {
test_host_interface::test_all().await;
});
}
fn exec_test_dht_key() {
async_std::task::block_on(async {
test_dht_key::test_all().await;
});
}
fn exec_test_veilid_core() {
async_std::task::block_on(async {
test_veilid_core::test_all().await;
});
}
fn exec_test_veilid_config() {
async_std::task::block_on(async {
test_veilid_config::test_all().await;
})
}
fn exec_test_async_peek_stream() {
async_std::task::block_on(async {
test_async_peek_stream::test_all().await;
})
}
fn exec_test_connection_table() {
async_std::task::block_on(async {
test_connection_table::test_all().await;
})
}
fn exec_test_table_store() {
async_std::task::block_on(async {
test_table_store::test_all().await;
})
}
fn exec_test_crypto() {
async_std::task::block_on(async {
test_crypto::test_all().await;
})
}
fn exec_test_envelope_receipt() {
async_std::task::block_on(async {
test_envelope_receipt::test_all().await;
})
}
///////////////////////////////////////////////////////////////////////////
cfg_if! {
if #[cfg(test)] {
use serial_test::serial;
use simplelog::*;
use std::sync::Once;
static SETUP_ONCE: Once = Once::new();
pub fn setup() -> () {
SETUP_ONCE.call_once(|| {
let mut cb = ConfigBuilder::new();
cb.add_filter_ignore_str("async_std");
cb.add_filter_ignore_str("async_io");
cb.add_filter_ignore_str("polling");
TestLogger::init(LevelFilter::Trace, cb.build()).unwrap();
});
}
#[test]
#[serial]
fn run_test_host_interface() {
setup();
exec_test_host_interface();
}
#[test]
#[serial]
fn run_test_dht_key() {
setup();
exec_test_dht_key();
}
#[test]
#[serial]
fn run_test_veilid_core() {
setup();
exec_test_veilid_core();
}
#[test]
#[serial]
fn run_test_veilid_config() {
setup();
exec_test_veilid_config();
}
#[test]
#[serial]
fn run_test_async_peek_stream() {
setup();
exec_test_async_peek_stream();
}
#[test]
#[serial]
fn run_test_connection_table() {
setup();
exec_test_connection_table();
}
#[test]
#[serial]
fn run_test_table_store() {
setup();
exec_test_table_store();
}
#[test]
#[serial]
fn run_test_crypto() {
setup();
exec_test_crypto();
}
#[test]
#[serial]
fn run_test_envelope_receipt() {
setup();
exec_test_envelope_receipt();
}
}
}
@@ -0,0 +1,280 @@
use crate::intf::utils::async_peek_stream::*;
use crate::xx::*;
use async_std::io;
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
use async_std::task;
use std::time::Duration;
static MESSAGE: &[u8; 62] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
async fn make_tcp_loopback() -> Result<(TcpStream, TcpStream), io::Error> {
let listener = TcpListener::bind("127.0.0.1:0").await?;
let local_addr = listener.local_addr()?;
let accept_future = async {
let (accepted_stream, peer_address) = listener.accept().await?;
trace!("connection from {}", peer_address);
accepted_stream.set_nodelay(true)?;
Result::<TcpStream, io::Error>::Ok(accepted_stream)
};
let connect_future = async {
task::sleep(Duration::from_secs(1)).await;
let connected_stream = TcpStream::connect(local_addr).await?;
connected_stream.set_nodelay(true)?;
Result::<TcpStream, io::Error>::Ok(connected_stream)
};
Ok(accept_future.try_join(connect_future).await?)
}
async fn make_async_peek_stream_loopback() -> (AsyncPeekStream, AsyncPeekStream) {
let (acc, conn) = make_tcp_loopback().await.unwrap();
let aps_a = AsyncPeekStream::new(acc);
let aps_c = AsyncPeekStream::new(conn);
(aps_a, aps_c)
}
async fn make_tcpstream_loopback() -> (TcpStream, TcpStream) {
make_tcp_loopback().await.unwrap()
}
pub async fn test_nothing() {
info!("test_nothing");
let (mut a, mut c) = make_tcpstream_loopback().await;
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
let mut inbuf: Vec<u8> = Vec::new();
inbuf.resize(outbuf.len(), 0u8);
c.read_exact(&mut inbuf).await.unwrap();
assert_eq!(inbuf, outbuf);
}
pub async fn test_no_peek() {
info!("test_no_peek");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
let mut inbuf: Vec<u8> = Vec::new();
inbuf.resize(outbuf.len(), 0u8);
c.read_exact(&mut inbuf).await.unwrap();
assert_eq!(inbuf, outbuf);
}
pub async fn test_peek_all_read() {
info!("test_peek_all_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek everything
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len(), 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// read everything
let mut inbuf: Vec<u8> = Vec::new();
inbuf.resize(outbuf.len(), 0u8);
c.read_exact(&mut inbuf).await.unwrap();
assert_eq!(inbuf, outbuf);
assert_eq!(peekbuf1, outbuf);
}
pub async fn test_peek_some_read() {
info!("test_peek_some_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek partially
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len() / 2, 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// read everything
let mut inbuf: Vec<u8> = Vec::new();
inbuf.resize(outbuf.len(), 0u8);
c.read_exact(&mut inbuf).await.unwrap();
assert_eq!(inbuf, outbuf);
assert_eq!(peekbuf1, outbuf[0..peeksize1].to_vec());
}
pub async fn test_peek_some_peek_some_read() {
info!("test_peek_some_peek_some_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek partially
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len() / 4, 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// peek partially
let mut peekbuf2: Vec<u8> = Vec::new();
peekbuf2.resize(peeksize1 + 1, 0u8);
let peeksize2 = c.peek(&mut peekbuf2).await.unwrap();
assert_eq!(peeksize2, peekbuf2.len());
// read everything
let mut inbuf: Vec<u8> = Vec::new();
inbuf.resize(outbuf.len(), 0u8);
c.read_exact(&mut inbuf).await.unwrap();
assert_eq!(inbuf, outbuf);
assert_eq!(peekbuf1, outbuf[0..peeksize1].to_vec());
assert_eq!(peekbuf2, outbuf[0..peeksize2].to_vec());
}
pub async fn test_peek_some_read_peek_some_read() {
info!("test_peek_some_read_peek_some_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek partially
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len() / 4, 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// read partially
let mut inbuf1: Vec<u8> = Vec::new();
inbuf1.resize(peeksize1 - 1, 0u8);
c.read_exact(&mut inbuf1).await.unwrap();
// peek partially
let mut peekbuf2: Vec<u8> = Vec::new();
peekbuf2.resize(2, 0u8);
let peeksize2 = c.peek(&mut peekbuf2).await.unwrap();
assert_eq!(peeksize2, peekbuf2.len());
// read partially
let mut inbuf2: Vec<u8> = Vec::new();
inbuf2.resize(2, 0u8);
c.read_exact(&mut inbuf2).await.unwrap();
assert_eq!(peekbuf1, outbuf[0..peeksize1].to_vec());
assert_eq!(inbuf1, outbuf[0..peeksize1 - 1].to_vec());
assert_eq!(peekbuf2, outbuf[peeksize1 - 1..peeksize1 + 1].to_vec());
assert_eq!(inbuf2, peekbuf2);
}
pub async fn test_peek_some_read_peek_all_read() {
info!("test_peek_some_read_peek_all_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek partially
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len() / 4, 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// read partially
let mut inbuf1: Vec<u8> = Vec::new();
inbuf1.resize(peeksize1 + 1, 0u8);
c.read_exact(&mut inbuf1).await.unwrap();
// peek past end
let mut peekbuf2: Vec<u8> = Vec::new();
peekbuf2.resize(outbuf.len(), 0u8);
let peeksize2 = c.peek(&mut peekbuf2).await.unwrap();
assert_eq!(peeksize2, outbuf.len() - (peeksize1 + 1));
// read remaining
let mut inbuf2: Vec<u8> = Vec::new();
inbuf2.resize(peeksize2, 0u8);
c.read_exact(&mut inbuf2).await.unwrap();
assert_eq!(peekbuf1, outbuf[0..peeksize1].to_vec());
assert_eq!(inbuf1, outbuf[0..peeksize1 + 1].to_vec());
assert_eq!(
peekbuf2[0..peeksize2].to_vec(),
outbuf[peeksize1 + 1..outbuf.len()].to_vec()
);
assert_eq!(inbuf2, peekbuf2[0..peeksize2].to_vec());
}
pub async fn test_peek_some_read_peek_some_read_all_read() {
info!("test_peek_some_read_peek_some_read_peek_all_read");
let (mut a, mut c) = make_async_peek_stream_loopback().await;
// write everything
let outbuf = MESSAGE.to_vec();
a.write_all(&outbuf).await.unwrap();
// peek partially
let mut peekbuf1: Vec<u8> = Vec::new();
peekbuf1.resize(outbuf.len() / 4, 0u8);
let peeksize1 = c.peek(&mut peekbuf1).await.unwrap();
assert_eq!(peeksize1, peekbuf1.len());
// read partially
let mut inbuf1: Vec<u8> = Vec::new();
inbuf1.resize(peeksize1 - 1, 0u8);
c.read_exact(&mut inbuf1).await.unwrap();
// peek partially
let mut peekbuf2: Vec<u8> = Vec::new();
peekbuf2.resize(2, 0u8);
let peeksize2 = c.peek(&mut peekbuf2).await.unwrap();
assert_eq!(peeksize2, peekbuf2.len());
// read partially
let mut inbuf2: Vec<u8> = Vec::new();
inbuf2.resize(1, 0u8);
c.read_exact(&mut inbuf2).await.unwrap();
// read remaining
let mut inbuf3: Vec<u8> = Vec::new();
inbuf3.resize(outbuf.len() - peeksize1, 0u8);
c.read_exact(&mut inbuf3).await.unwrap();
assert_eq!(peekbuf1, outbuf[0..peeksize1].to_vec());
assert_eq!(inbuf1, outbuf[0..peeksize1 - 1].to_vec());
assert_eq!(
peekbuf2[0..peeksize2].to_vec(),
outbuf[peeksize1 - 1..peeksize1 + 1].to_vec()
);
assert_eq!(inbuf2, peekbuf2[0..1].to_vec());
assert_eq!(inbuf3, outbuf[peeksize1..outbuf.len()].to_vec());
}
pub async fn test_all() {
test_nothing().await;
test_no_peek().await;
test_peek_all_read().await;
test_peek_some_read().await;
test_peek_some_peek_some_read().await;
test_peek_some_read_peek_some_read().await;
test_peek_some_read_peek_all_read().await;
test_peek_some_read_peek_some_read_all_read().await;
}