Magisk/scripts/test_common.sh
topjohnwu 32faa4ced6 Redesign test APK architecture
The test APK and the main APK share the same process and classloader,
and in the non-hidden case, the test APK's classes take precedence over
the ones in the main APK. This causes issues because the test APK and
main APK share some dependencies, but don't always use the same
version. This is especially problematic for the Kotlin stdlib and
AndroidX dependencies.

The solution here is to rely on R8's obfuscation feature and repackage
all potentially conflicting classes into a separate package in the test
APK. To ensure that the test classes are always using the same classes
as the main APK, we have to directly implement all tests inside the main
APK, making the test APK purely a "test runner with test dependencies".

As a result, the test APK can only be used when built in release mode,
because R8 no longer allow class obfuscation to be enabled when building
for debug versions.
2024-12-25 20:17:57 -08:00

93 lines
2.2 KiB
Bash

if [ -z $ANDROID_HOME ]; then
export ANDROID_HOME=$ANDROID_SDK_ROOT
fi
# Make sure paths are consistent
export ANDROID_USER_HOME="$HOME/.android"
export ANDROID_EMULATOR_HOME="$ANDROID_USER_HOME"
export ANDROID_AVD_HOME="$ANDROID_EMULATOR_HOME/avd"
export PATH="$PATH:$ANDROID_HOME/platform-tools"
emu="$ANDROID_HOME/emulator/emulator"
sdk="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
avd="$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager"
boot_timeout=600
core_count=$(nproc)
if [ $core_count -gt 8 ]; then
core_count=8
fi
print_title() {
echo -e "\n\033[44;39m${1}\033[0m\n"
}
print_error() {
echo -e "\n\033[41;39m${1}\033[0m\n"
}
# $1 = TestClass#method
# $2: boolean = isRepackaged
am_instrument() {
local test_pkg
if [ -n "$2" -a "$2" ]; then
test_pkg="repackaged.com.topjohnwu.magisk.test"
else
test_pkg=com.topjohnwu.magisk.test
fi
local out=$(adb shell am instrument -w --user 0 \
-e class "com.topjohnwu.magisk.test.$1" \
"$test_pkg/com.topjohnwu.magisk.test.TestRunner")
grep -q 'OK (' <<< "$out"
}
# $1 = pkg
wait_for_pm() {
sleep 5
adb shell pm uninstall $1 || true
}
run_setup() {
local variant=$1
adb shell 'PATH=$PATH:/debug_ramdisk magisk -v'
# Install the Magisk app
adb install -r -g out/app-${variant}.apk
# Install the test app
adb install -r -g out/test.apk
# Run setup through the test app
am_instrument 'Environment#setupMagisk'
}
run_tests() {
# Run app tests
am_instrument 'MagiskAppTest'
# Test shell su request
am_instrument 'Environment#setupShellGrantTest'
adb shell /system/xbin/su 2000 su -c id | tee /dev/fd/2 | grep -q 'uid=0'
adb shell am force-stop com.topjohnwu.magisk
# Test app hiding
am_instrument 'Environment#setupAppHide'
wait_for_pm com.topjohnwu.magisk
# Make sure it still works
am_instrument 'MagiskAppTest' true
# Test shell su request
am_instrument 'Environment#setupShellGrantTest' true
adb shell /system/xbin/su 2000 su -c id | tee /dev/fd/2 | grep -q 'uid=0'
adb shell am force-stop repackaged.com.topjohnwu.magisk
# Test app restore
am_instrument 'Environment#setupAppRestore' true
wait_for_pm repackaged.com.topjohnwu.magisk
# Make sure it still works
am_instrument 'MagiskAppTest'
}