From 1793dd90e84c85a10bc9dbab768981778fa8e4e7 Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 23 Aug 2022 10:37:41 -0400 Subject: [PATCH] fix android unit tests and add better macos instructions --- README.md | 81 ++++++++++++++++-- setup_linux.sh | 19 ++++- setup_macos.sh | 82 +++++++++++++++++-- .../native/utils/network_interfaces/mod.rs | 8 -- veilid-core/src/network_manager/native/mod.rs | 27 ++++-- .../network_manager/native/start_protocols.rs | 43 +++------- veilid-core/src/network_manager/wasm/mod.rs | 11 +-- .../src/tests/android/.idea/gradle.xml | 3 +- veilid-core/src/tests/android/.idea/misc.xml | 2 +- veilid-core/src/tests/android/adb+.sh | 20 +++++ .../src/tests/android/app/build.gradle | 1 + .../tests/android/install_on_all_devices.sh | 2 + .../tests/android/remove_from_all_devices.sh | 3 + 13 files changed, 227 insertions(+), 75 deletions(-) create mode 100755 veilid-core/src/tests/android/adb+.sh create mode 100755 veilid-core/src/tests/android/install_on_all_devices.sh create mode 100755 veilid-core/src/tests/android/remove_from_all_devices.sh diff --git a/README.md b/README.md index 65466167..82570882 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,13 @@ Development of Veilid on GNU/Linux requires a Debian variant such as Debian itself, Ubuntu or Mint. Pull requests to support other distributions would be welcome! -Development requires the Android SDK and NDK be installed. +Running the setup script requires: +* Android SDK and NDK +* Rust -You may decide to use Android Studio to maintain your Android dependencies. If -so, use the dependency manager within your IDE. If you do so, you may skip to +You may decide to use Android Studio [here](https://developer.android.com/studio) +to maintain your Android dependencies. If so, use the dependency manager +within your IDE. If you do so, you may skip to [Run Veilid setup script](#Run Veilid setup script). * build-tools;30.0.3 @@ -45,8 +48,9 @@ your path. ```shell cat << EOF >> ~/.profile export ANDROID_SDK_ROOT= -export ANDROID_NDK_HOME= -export PATH=${ANDROID_SDK_ROOT}/platform-tools" +export ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/22.0.7026061 +export PATH=\$PATH:$ANDROID_SDK_ROOT/platform-tools +EOF ``` #### Run Veilid setup script @@ -60,7 +64,72 @@ pull the remaining Rust dependencies: ### macOS -**TODO** +Development of Veilid on MacOS is possible on both Intel and ARM hardware. + +Development requires: +* Xcode, preferably latest version +* Homebrew [here](https://brew.sh) +* Android SDK and NDK +* Java 8 +* Rust + +You may decide to use Android Studio [here](https://developer.android.com/studio) +to maintain your Android dependencies. If so, use the dependency manager +within your IDE. If you do so, you may skip to +[Run Veilid setup script](#Run Veilid setup script). + +* build-tools;30.0.3 +* ndk;22.0.7026061 +* cmake;3.22.1 + +#### Setup Java + +```shell +brew install openjdk@8 +``` +and then symlink it as appropriate for your system: + +Intel: +```shell +sudo ln -sfn /usr/local/opt/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk +``` + +ARM: +```shell +sudo ln -sfn /opt/homebrew/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk +``` + + +#### Setup Dependencies using the CLI + +Otherwise, you may choose to use Android `sdkmanager`. Use +the command line to install the requisite package versions: `brew install android-commandlinetools` + +```shell +sdkmanager --install "build-tools;30.0.3" +sdkmanager --install "ndk;22.0.7026061" +sdkmanager --install "cmake;3.22.1" +``` + +Export environment variables and add the Android SDK platform-tools directory to +your path. + +```shell +cat << EOF >> ~/.zshenv +export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk +export ANDROID_NDK_HOME=$HOME/Library/Android/sdk/ndk/22.0.7026061 +export PATH=\$PATH:$HOME/Library/Android/sdk/platform-tools +EOF +``` + +#### Run Veilid setup script + +Now you may run the MacOS setup script to check your development environment and +pull the remaining Rust dependencies: + +```shell +./setup_macos.sh +``` ### Windows diff --git a/setup_linux.sh b/setup_linux.sh index d7846a26..cf6c4cd9 100755 --- a/setup_linux.sh +++ b/setup_linux.sh @@ -14,7 +14,6 @@ else exit 1 fi - # ensure ANDROID_NDK_HOME is defined and exists if [ -d "$ANDROID_NDK_HOME" ]; then echo '[X] $ANDROID_NDK_HOME is defined and exists' @@ -55,8 +54,24 @@ else exit 1 fi +# ensure rustup is installed +if command -v rustup &> /dev/null; then + echo '[X] rustup is available in the path' +else + echo 'rustup is not available in the path' + exit 1 +fi + +# ensure cargo is installed +if command -v cargo &> /dev/null; then + echo '[X] cargo is available in the path' +else + echo 'cargo is not available in the path' + exit 1 +fi + # install targets -rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android +rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android wasm32-unknown-unknown # install cargo packages cargo install wasm-bindgen-cli diff --git a/setup_macos.sh b/setup_macos.sh index 273743ea..fc24a87e 100755 --- a/setup_macos.sh +++ b/setup_macos.sh @@ -6,17 +6,53 @@ if [ ! "$(uname)" == "Darwin" ]; then exit 1 fi -# install targets -rustup target add aarch64-apple-darwin aarch64-apple-ios x86_64-apple-darwin x86_64-apple-ios wasm32-unknown-unknown +# ensure ANDROID_SDK_ROOT is defined and exists +if [ -d "$ANDROID_SDK_ROOT" ]; then + echo '[X] $ANDROID_SDK_ROOT is defined and exists' +else + echo '$ANDROID_SDK_ROOT is not defined or does not exist' + exit 1 +fi -# install cargo packages -cargo install wasm-bindgen-cli +# ensure ANDROID_NDK_HOME is defined and exists +if [ -d "$ANDROID_NDK_HOME" ]; then + echo '[X] $ANDROID_NDK_HOME is defined and exists' +else + echo '$ANDROID_NDK_HOME is not defined or does not exist' + exit 1 +fi -# install bitcode compatible ios toolchain -# echo Manual Step: -# echo install +ios-arm64-1.57.0 toolchain for bitcode from https://github.com/getditto/rust-bitcode/releases/latest and unzip -# echo xattr -d -r com.apple.quarantine . -# echo ./install.sh +# ensure ndk is installed +if [ -f "$ANDROID_NDK_HOME/ndk-build" ]; then + echo '[X] Android NDK is installed at the location $ANDROID_NDK_HOME' +else + echo 'Android NDK is not installed at the location $ANDROID_NDK_HOME' + exit 1 +fi + +# ensure cmake is installed +if [ -d "$ANDROID_SDK_ROOT/cmake" ]; then + echo '[X] Android SDK CMake is installed' +else + echo 'Android SDK CMake is not installed' + exit 1 +fi + +# ensure emulator is installed +if [ -d "$ANDROID_SDK_ROOT/emulator" ]; then + echo '[X] Android SDK emulator is installed' +else + echo 'Android SDK emulator is not installed' + exit 1 +fi + +# ensure adb is installed +if command -v adb &> /dev/null; then + echo '[X] adb is available in the path' +else + echo 'adb is not available in the path' + exit 1 +fi # ensure brew is installed if command -v brew &> /dev/null; then @@ -34,6 +70,34 @@ else exit 1 fi +# ensure rustup is installed +if command -v rustup &> /dev/null; then + echo '[X] rustup is available in the path' +else + echo 'rustup is not available in the path' + exit 1 +fi + +# ensure cargo is installed +if command -v cargo &> /dev/null; then + echo '[X] cargo is available in the path' +else + echo 'cargo is not available in the path' + exit 1 +fi + +# install targets +rustup target add aarch64-apple-darwin aarch64-apple-ios x86_64-apple-darwin x86_64-apple-ios wasm32-unknown-unknown aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android + +# install cargo packages +cargo install wasm-bindgen-cli + +# install bitcode compatible ios toolchain +# echo Manual Step: +# echo install +ios-arm64-1.57.0 toolchain for bitcode from https://github.com/getditto/rust-bitcode/releases/latest and unzip +# echo xattr -d -r com.apple.quarantine . +# echo ./install.sh + # ensure we have command line tools xcode-select --install diff --git a/veilid-core/src/intf/native/utils/network_interfaces/mod.rs b/veilid-core/src/intf/native/utils/network_interfaces/mod.rs index 79b4cefd..1b14053f 100644 --- a/veilid-core/src/intf/native/utils/network_interfaces/mod.rs +++ b/veilid-core/src/intf/native/utils/network_interfaces/mod.rs @@ -385,14 +385,6 @@ impl NetworkInterfaces { inner.interface_address_cache.clone() } - pub fn with_best_addresses(&self, f: F) -> R - where - F: FnOnce(&[IpAddr]) -> R, - { - let inner = self.inner.lock(); - f(&inner.interface_address_cache) - } - ///////////////////////////////////////////// fn cache_best_addresses(inner: &mut NetworkInterfacesInner) { diff --git a/veilid-core/src/network_manager/native/mod.rs b/veilid-core/src/network_manager/native/mod.rs index 9428e2eb..c8ab9101 100644 --- a/veilid-core/src/network_manager/native/mod.rs +++ b/veilid-core/src/network_manager/native/mod.rs @@ -268,9 +268,8 @@ impl Network { if !from.ip().is_unspecified() { vec![*from] } else { - self.unlocked_inner - .interfaces - .best_addresses() + let addrs = self.get_usable_interface_addresses(); + addrs .iter() .filter_map(|a| { // We create sockets that are only ipv6 or ipv6 (not dual, so only translate matching unspecified address) @@ -311,11 +310,21 @@ impl Network { } } - pub fn with_interface_addresses(&self, f: F) -> R - where - F: FnOnce(&[IpAddr]) -> R, - { - self.unlocked_inner.interfaces.with_best_addresses(f) + pub fn is_usable_interface_address(&self, addr: IpAddr) -> bool { + let usable_addrs = self.get_usable_interface_addresses(); + usable_addrs.contains(&addr) + } + + pub fn get_usable_interface_addresses(&self) -> Vec { + let addrs = self.unlocked_inner.interfaces.best_addresses(); + let addrs: Vec = addrs + .into_iter() + .filter(|addr| { + let address = Address::from_ip_addr(*addr); + address.is_local() || address.is_global() + }) + .collect(); + addrs } // See if our interface addresses have changed, if so we need to punt the network @@ -591,7 +600,7 @@ impl Network { { let mut inner = self.inner.lock(); inner.enable_ipv4 = false; - for addr in self.unlocked_inner.interfaces.best_addresses() { + for addr in self.get_usable_interface_addresses() { if addr.is_ipv4() { log_net!(debug "enable address {:?} as ipv4", addr); inner.enable_ipv4 = true; diff --git a/veilid-core/src/network_manager/native/start_protocols.rs b/veilid-core/src/network_manager/native/start_protocols.rs index 687408b5..3843a36c 100644 --- a/veilid-core/src/network_manager/native/start_protocols.rs +++ b/veilid-core/src/network_manager/native/start_protocols.rs @@ -332,14 +332,15 @@ impl Network { } // See if this public address is also a local interface address we haven't registered yet - let is_interface_address = self.with_interface_addresses(|ip_addrs| { - for ip_addr in ip_addrs { - if pdi_addr.ip() == *ip_addr { + let is_interface_address = (|| { + for ip_addr in self.get_usable_interface_addresses() { + if pdi_addr.ip() == ip_addr { return true; } } false - }); + })(); + if !local_dial_info_list.contains(&pdi) && is_interface_address { routing_table.register_dial_info( RoutingDomain::LocalNetwork, @@ -428,15 +429,9 @@ impl Network { } // See if this public address is also a local interface address - let is_interface_address = self.with_interface_addresses(|ip_addrs| { - for ip_addr in ip_addrs { - if gsa.ip() == *ip_addr { - return true; - } - } - false - }); - if !registered_addresses.contains(&gsa.ip()) && is_interface_address { + if !registered_addresses.contains(&gsa.ip()) + && self.is_usable_interface_address(gsa.ip()) + { routing_table.register_dial_info( RoutingDomain::LocalNetwork, pdi, @@ -559,15 +554,9 @@ impl Network { } // See if this public address is also a local interface address - let is_interface_address = self.with_interface_addresses(|ip_addrs| { - for ip_addr in ip_addrs { - if gsa.ip() == *ip_addr { - return true; - } - } - false - }); - if !registered_addresses.contains(&gsa.ip()) && is_interface_address { + if !registered_addresses.contains(&gsa.ip()) + && self.is_usable_interface_address(gsa.ip()) + { routing_table.register_dial_info( RoutingDomain::LocalNetwork, pdi, @@ -679,15 +668,7 @@ impl Network { } // See if this public address is also a local interface address - let is_interface_address = self.with_interface_addresses(|ip_addrs| { - for ip_addr in ip_addrs { - if pdi_addr.ip() == *ip_addr { - return true; - } - } - false - }); - if is_interface_address { + if self.is_usable_interface_address(pdi_addr.ip()) { routing_table.register_dial_info( RoutingDomain::LocalNetwork, pdi, diff --git a/veilid-core/src/network_manager/wasm/mod.rs b/veilid-core/src/network_manager/wasm/mod.rs index b96f9564..89c0a0b2 100644 --- a/veilid-core/src/network_manager/wasm/mod.rs +++ b/veilid-core/src/network_manager/wasm/mod.rs @@ -282,15 +282,12 @@ impl Network { trace!("network stopped"); } - pub fn with_interface_addresses(&self, f: F) -> R - where - F: FnOnce(&[IpAddr]) -> R, - { - f(&[]) + pub fn is_usable_interface_address(&self, addr: IpAddr) -> bool { + false } - pub async fn check_interface_addresses(&self) -> EyreResult { - Ok(false) + pub fn get_usable_interface_addresses(&self) -> Vec { + Vec::new() } ////////////////////////////////////////// diff --git a/veilid-core/src/tests/android/.idea/gradle.xml b/veilid-core/src/tests/android/.idea/gradle.xml index cc2be694..4989a70a 100644 --- a/veilid-core/src/tests/android/.idea/gradle.xml +++ b/veilid-core/src/tests/android/.idea/gradle.xml @@ -8,14 +8,13 @@ - diff --git a/veilid-core/src/tests/android/.idea/misc.xml b/veilid-core/src/tests/android/.idea/misc.xml index 860da66a..ef61796f 100644 --- a/veilid-core/src/tests/android/.idea/misc.xml +++ b/veilid-core/src/tests/android/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/veilid-core/src/tests/android/adb+.sh b/veilid-core/src/tests/android/adb+.sh new file mode 100755 index 00000000..5aa7fbbf --- /dev/null +++ b/veilid-core/src/tests/android/adb+.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Script adb+ +# Usage +# You can run any command adb provide on all your current devices +# ./adb+ is the equivalent of ./adb -s +# +# Examples +# ./adb+ version +# ./adb+ install apidemo.apk +# ./adb+ uninstall com.example.android.apis + +adb devices | while read line +do + if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ] + then + device=`echo $line | awk '{print $1}'` + echo "$device $@ ..." + adb -s $device $@ + fi +done diff --git a/veilid-core/src/tests/android/app/build.gradle b/veilid-core/src/tests/android/app/build.gradle index cd66b082..25ad2c38 100644 --- a/veilid-core/src/tests/android/app/build.gradle +++ b/veilid-core/src/tests/android/app/build.gradle @@ -67,6 +67,7 @@ cargo { targetDirectory = "../../../../../target" prebuiltToolchains = true profile = gradle.startParameter.taskNames.any{it.toLowerCase().contains("debug")} ? "debug" : "release" + pythonCommand = "python3" features { defaultAnd("android_tests", "rt-tokio") } diff --git a/veilid-core/src/tests/android/install_on_all_devices.sh b/veilid-core/src/tests/android/install_on_all_devices.sh new file mode 100755 index 00000000..f96d53b1 --- /dev/null +++ b/veilid-core/src/tests/android/install_on_all_devices.sh @@ -0,0 +1,2 @@ +#!/bin/bash +./gradlew installDebug diff --git a/veilid-core/src/tests/android/remove_from_all_devices.sh b/veilid-core/src/tests/android/remove_from_all_devices.sh new file mode 100755 index 00000000..d3eace9d --- /dev/null +++ b/veilid-core/src/tests/android/remove_from_all_devices.sh @@ -0,0 +1,3 @@ +#!/bin/bash +./adb+.sh uninstall com.veilid.veilidcore.veilidcore_android_tests +