Skip to content

Commit

Permalink
Android CI with Unit Testing (#295)
Browse files Browse the repository at this point in the history
* Add android CI scripts

* Android Test Driver: Busybox compatibility
  • Loading branch information
hmelder authored Jul 9, 2024
1 parent 2855d17 commit b35505f
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 0 deletions.
61 changes: 61 additions & 0 deletions .github/scripts/android_test_driver.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/sh

# This script is run on the emulator to run the tests

# Get list of all binaries in pwd for later iteration (only include binaries)
BINARIES=$(find . -maxdepth 1 -type f ! -name "*.so" ! -name "android_test_driver.sh")

TOTAL=0
PASS=0
SKIP=0
FAIL=0

# Run each binary, measure time and return value (PASS or FAIL). Print stdout and stderr only after a failure
for BINARY in $BINARIES; do
TOTAL=$((TOTAL + 1))

START_TIME=$(date +%s)
START_TIME_MS=$((START_TIME * 1000 + $(date +%N) / 1000000))

OUTPUT=$("$BINARY" 2>&1)
EXIT_CODE=$?

END_TIME=$(date +%s)
END_TIME_MS=$((END_TIME * 1000 + $(date +%N) / 1000000))
ELAPSED_TIME=$((END_TIME_MS - START_TIME_MS))

BINARY_NAME=$(basename "$BINARY")

if [ $EXIT_CODE -eq 0 ]; then
PASS=$((PASS + 1))
echo "PASSED ($EXIT_CODE): $BINARY_NAME (${ELAPSED_TIME}ms)"
elif [ $EXIT_CODE -eq 77 ]; then
SKIP=$((SKIP + 1))
echo "SKIPPED: $BINARY_NAME"
else
FAIL=$((FAIL + 1))
echo "FAILED ($EXIT_CODE): $BINARY_NAME (${ELAPSED_TIME}ms)"
if [ -z "$OUTPUT" ]; then
echo "No output written to stdout."
else
echo "Output:"
echo "$OUTPUT"
fi
fi
done

if [ $TOTAL -eq 0 ]; then
echo "No tests found. Exiting."
exit 1
fi

PERCENTAGE=$(((PASS + SKIP) * 100 / TOTAL))
echo "$PERCENTAGE% Passed. Total: $TOTAL, Passed: $PASS, Skipped: $SKIP, Failed: $FAIL"
echo "Finished running tests. Exiting."

# Exit with corresponding return value
if [ $FAIL -eq 0 ]; then
exit 0
else
exit 1
fi
63 changes: 63 additions & 0 deletions .github/scripts/android_test_main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/sh

main () {
# first argument is the build directory
local BUILD_DIR=$1
# second argument is the android ndk sysroot
local ANDROID_NDK_SYSROOT=$2
# third argument is the target triple
# e.g. arm-linux-androideabi, aarch64-linux-android, x86_64-linux-android
local TARGET_TRIPLE=$3

if [ ! -d "$BUILD_DIR" ]
then
echo "Build directory argument not found"
exit 1
fi
if [ ! -d "$ANDROID_NDK_SYSROOT" ]
then
echo "Android NDK sysroot argument not found"
exit 1
fi
if [ -z "$TARGET_TRIPLE" ]
then
echo "Target triple argument not found"
exit 1
fi

# We need to run the emulator with root permissions
# This is needed to run the tests
adb root

local TEMP_DIR=$(mktemp -d)

# Copy libobjc.so and test binaries to temporary directory
cp $BUILD_DIR/libobjc.so* $TEMP_DIR
cp $BUILD_DIR/Test/* $TEMP_DIR

for file in $TEMP_DIR/*; do
# Check if file is a binary
if ! file $file | grep -q "ELF"
then
rm $file
continue
fi

# Set runtime path to ORIGIN
patchelf --set-rpath '$ORIGIN' $file
done

# Copy libc++_shared.so (required by libobjc2)
cp $ANDROID_NDK_SYSROOT/usr/lib/$TARGET_TRIPLE/libc++_shared.so $TEMP_DIR

adb shell rm -rf /data/local/tmp/libobjc2_tests
adb push $TEMP_DIR /data/local/tmp/libobjc2_tests

# Copy android_test_driver.sh to device
adb push $BUILD_DIR/../.github/scripts/android_test_driver.sh /data/local/tmp/libobjc2_tests

# Run the tests
adb shell "cd /data/local/tmp/libobjc2_tests && sh android_test_driver.sh"
}

main "$@"
73 changes: 73 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,79 @@ jobs:
name: ${{ matrix.msystem }}-${{ matrix.build-type }}
path: dist/

android:
strategy:
matrix:
# Build each combination of OS and release/debug variants
os: [ ubuntu-20.04 ]
build-type: [ Release, Debug ]
arch:
- name: x86_64
triple: x86_64-linux-android
api-level: [ 26 ]
# Don't abort runners if a single one fails
fail-fast: false
runs-on: ${{ matrix.os }}
name: Android ${{ matrix.build-type }} ${{ matrix.arch.name }} API-${{ matrix.api-level }}
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
sudo apt-get update -y
sudo apt-get install patchelf ninja-build -y
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r26d
- name: Configure CMake
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
export CCPREFIX=$TOOLCHAIN/bin/${{ matrix.arch.triple }}${{ matrix.api-level }}
export CC="$CCPREFIX-clang"
export CXX="$CCPREFIX-clang++"
export OBJC="$CCPREFIX-clang"
export OBJCXX="$CCPREFIX-clang++"
export AS="$CCPREFIX-clang"
export LD="$TOOLCHAIN/bin/ld.lld"
export AR="$TOOLCHAIN/bin/llvm-ar"
export RANLIB="$TOOLCHAIN/bin/llvm-ranlib"
export STRIP="$TOOLCHAIN/bin/llvm-strip"
export NM="$TOOLCHAIN/bin/llvm-nm"
export OBJDUMP="$TOOLCHAIN/bin/llvm-objdump"
export LDFLAGS="-fuse-ld=lld"
export LIBS="-lc++_shared"
cmake -B ${{github.workspace}}/build \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=${{ matrix.arch.name }} \
-DANDROID_NDK=$ANDROID_NDK_HOME \
-DANDROID_STL=c++_shared \
-DCMAKE_FIND_USE_CMAKE_PATH=false \
-DCMAKE_C_COMPILER=$CC \
-DCMAKE_CXX_COMPILER=$CXX \
-DCMAKE_ASM_COMPILER=$AS \
-DCMAKE_BUILD_TYPE=${{matrix.build-type}} \
-DTESTS=ON \
-DANDROID_PLATFORM=android-${{ matrix.api-level }} \
-G Ninja
- name: Build
working-directory: ${{github.workspace}}/build
run: |
NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja -v
- name: Test
uses: reactivecircus/android-emulator-runner@v2
env:
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
with:
api-level: ${{ matrix.api-level }}
target: default
arch: ${{ matrix.arch.name }}
script: |
${{github.workspace}}/.github/scripts/android_test_main.sh ${{github.workspace}}/build ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot ${{ matrix.arch.triple }}
# Fake check that can be used as a branch-protection rule.
all-checks:
needs: [ubuntu, windows, qemu-crossbuild]
Expand Down

0 comments on commit b35505f

Please sign in to comment.