Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android] Implement android test runner for core unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alexshalamov committed Dec 21, 2018
1 parent bd4a059 commit d8cc12b
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 113 deletions.
22 changes: 8 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ MBGL_ANDROID_ABIS += x86-64;x86_64
MBGL_ANDROID_LOCAL_WORK_DIR = /data/local/tmp/core-tests
MBGL_ANDROID_LIBDIR = lib$(if $(filter arm-v8 x86-64,$1),64)
MBGL_ANDROID_DALVIKVM = dalvikvm$(if $(filter arm-v8 x86-64,$1),64,32)
MBGL_ANDROID_APK_SUFFIX = $(if $(filter Release,$(BUILDTYPE)),release-unsigned,debug)
MBGL_ANDROID_APK_SUFFIX = $(if $(filter Release,$(BUILDTYPE)),release,debug)
MBGL_ANDROID_CORE_TEST_DIR = platform/android/MapboxGLAndroidSDK/.externalNativeBuild/cmake/$(buildtype)/$2/core-tests
MBGL_ANDROID_STL ?= c++_static
MBGL_ANDROID_GRADLE = ./gradlew --parallel --max-workers=$(JOBS) -Pmapbox.buildtype=$(buildtype) -Pmapbox.stl=$(MBGL_ANDROID_STL)
Expand Down Expand Up @@ -542,27 +542,21 @@ android-$1: platform/android/gradle/configuration.gradle
android-core-test-$1: android-test-lib-$1
# Compile main sources and extract the classes (using the test app to get all transitive dependencies in one place)
mkdir -p $(MBGL_ANDROID_CORE_TEST_DIR)
unzip -o platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-$(MBGL_ANDROID_APK_SUFFIX).apk classes.dex -d $(MBGL_ANDROID_CORE_TEST_DIR)

# Compile Test runner
find platform/android/src/test -name "*.java" > $(MBGL_ANDROID_CORE_TEST_DIR)/java-sources.txt
javac -sourcepath platform/android/src/test -d $(MBGL_ANDROID_CORE_TEST_DIR) -source 1.7 -target 1.7 @$(MBGL_ANDROID_CORE_TEST_DIR)/java-sources.txt

# Combine and dex
cd $(MBGL_ANDROID_CORE_TEST_DIR) && $(ANDROID_HOME)/build-tools/25.0.0/dx --dex --output=test.jar *.class classes.dex
unzip -o platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/$(buildtype)/MapboxGLAndroidSDKTestApp-$(MBGL_ANDROID_APK_SUFFIX).apk classes.dex -d $(MBGL_ANDROID_CORE_TEST_DIR)

run-android-core-test-$1-%: android-core-test-$1
# Ensure clean state on the device
adb shell "rm -Rf $(MBGL_ANDROID_LOCAL_WORK_DIR) && mkdir -p $(MBGL_ANDROID_LOCAL_WORK_DIR)/test"
adb shell "rm -Rf $(MBGL_ANDROID_LOCAL_WORK_DIR) && mkdir -p $(MBGL_ANDROID_LOCAL_WORK_DIR)/test && mkdir -p $(MBGL_ANDROID_LOCAL_WORK_DIR)/mapbox-gl-js/src/style-spec/reference"

# Push all needed files to the device
adb push $(MBGL_ANDROID_CORE_TEST_DIR)/test.jar $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
adb push $(MBGL_ANDROID_CORE_TEST_DIR)/classes.dex $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
adb push platform/android/MapboxGLAndroidSDK/build/intermediates/intermediate-jars/$(buildtype)/jni/$2/libmapbox-gl.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
adb push test/fixtures $(MBGL_ANDROID_LOCAL_WORK_DIR)/test > /dev/null 2>&1
adb push platform/android/MapboxGLAndroidSDK/build/intermediates/bundles/default/jni/$2/libmapbox-gl.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
adb push platform/android/MapboxGLAndroidSDK/build/intermediates/bundles/default/jni/$2/libmbgl-test.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
adb push mapbox-gl-js/src/style-spec/reference/v8.json $(MBGL_ANDROID_LOCAL_WORK_DIR)/mapbox-gl-js/src/style-spec/reference > /dev/null 2>&1
adb push platform/android/MapboxGLAndroidSDK/build/intermediates/cmake/$(buildtype)/obj/$2/mbgl-test $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1

# Kick off the tests
adb shell "export LD_LIBRARY_PATH=/system/$(MBGL_ANDROID_LIBDIR):$(MBGL_ANDROID_LOCAL_WORK_DIR) && cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && $(MBGL_ANDROID_DALVIKVM) -cp $(MBGL_ANDROID_LOCAL_WORK_DIR)/test.jar Main --gtest_filter=$$*"
adb shell "export LD_LIBRARY_PATH=$(MBGL_ANDROID_LOCAL_WORK_DIR) && cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && chmod +x mbgl-test && ./mbgl-test --class_path=$(MBGL_ANDROID_LOCAL_WORK_DIR)/classes.dex --gtest_filter=$$*"

# Gather the results and unpack them
adb shell "cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && tar -cvzf results.tgz test/fixtures/* > /dev/null 2>&1"
Expand Down
18 changes: 10 additions & 8 deletions platform/android/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,25 @@ target_link_libraries(mapbox-gl
PRIVATE mbgl-filesource
)

## Test library ##

set(MBGL_TEST_TARGET_TYPE "library")
## Test executable ##
macro(mbgl_platform_test)
target_sources(mbgl-test
PRIVATE platform/default/src/mbgl/test/main.cpp

# Main test entry point
platform/android/src/test/main.jni.cpp
PRIVATE platform/android/src/test/test_runner.cpp
PRIVATE platform/android/src/test/runtime.cpp
)

target_include_directories(mbgl-test
PRIVATE platform/android
)

set_target_properties(mbgl-test
PROPERTIES
LINK_FLAGS
"-fPIE -pie \
-Wl,--export-dynamic \
-Wl,--version-script=${CMAKE_SOURCE_DIR}/platform/android/src/test/version-script")

target_link_libraries(mbgl-test
PRIVATE mbgl-core
PRIVATE mbgl-filesource
)
endmacro()
Expand Down
15 changes: 0 additions & 15 deletions platform/android/src/test/Main.java

This file was deleted.

76 changes: 0 additions & 76 deletions platform/android/src/test/main.jni.cpp

This file was deleted.

73 changes: 73 additions & 0 deletions platform/android/src/test/runtime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "runtime.hpp"
#include "../jni.hpp"

#include <cassert>
#include <dlfcn.h>
#include <jni.h>
#include <signal.h>
#include <string>

// Required for art / libsigchain
extern "C" JNIEXPORT void EnsureFrontOfChain(int, struct sigaction*) { }
extern "C" JNIEXPORT void AddSpecialSignalHandlerFn(int, void*) { }
extern "C" JNIEXPORT void RemoveSpecialSignalHandlerFn(int, bool (*) (int, siginfo_t*, void*)) { }

namespace {
const std::string kClassPathCommand{"--class_path="};
const std::string kClassPath{"-Djava.class.path="};
const std::string kDefaultDex{"/data/local/tmp/core-tests/classes.dex"};
} // namespace

namespace mbgl {
namespace android {

bool init_runtime(int argc, char *argv[]) {
void* vmHandle = dlopen ("libart.so", RTLD_NOW);
assert(vmHandle != nullptr);

using CreateJavaVMFn = jint (*) (JavaVM ** vm, JNIEnv ** env, void * vmArgs);
CreateJavaVMFn createJavaVMFn = reinterpret_cast<CreateJavaVMFn>(dlsym(vmHandle, "JNI_CreateJavaVM"));
assert(createJavaVMFn != nullptr);

std::string classPath = kClassPath + kDefaultDex;
for (int i = 0; i < argc; ++i) {
const std::string arg{argv[i]};
if (arg.compare(0, kClassPathCommand.length(), kClassPathCommand) == 0) {
classPath = kClassPath + arg.substr(kClassPathCommand.length());
break;
}
}

JavaVMOption options[1];
options[0].optionString = classPath.c_str();

JavaVMInitArgs args;
args.version = JNI_VERSION_1_6;
args.nOptions = 1;
args.options = options;
args.ignoreUnrecognized = JNI_TRUE;

JavaVM * vm;
JNIEnv * env;

if (createJavaVMFn(&vm, &env, &args) != JNI_OK) {
return false;
}

void* runtimeHandle = dlopen ("libandroid_runtime.so", RTLD_NOW);
assert(runtimeHandle != nullptr);

using RegisterNativesFn = jint (*) (JNIEnv * env);
RegisterNativesFn registerNativesFn = reinterpret_cast<RegisterNativesFn>(dlsym(runtimeHandle, "registerFrameworkNatives"));
assert(registerNativesFn != nullptr);

if (registerNativesFn(env) != JNI_OK) {
return false;
}

mbgl::android::registerNatives(vm);
return true;
}

} // namespace android
} // namespace mbgl
9 changes: 9 additions & 0 deletions platform/android/src/test/runtime.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace mbgl {
namespace android {

bool init_runtime(int argc, char *argv[]);

} // namespace android
} // namespace mbgl
10 changes: 10 additions & 0 deletions platform/android/src/test/test_runner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "runtime.hpp"
#include <mbgl/test.hpp>

int main(int argc, char *argv[]) {
if (!mbgl::android::init_runtime(argc, argv)) {
return 1;
}

mbgl::runTests(argc, argv);
}
8 changes: 8 additions & 0 deletions platform/android/src/test/version-script
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
global:
EnsureFrontOfChain;
AddSpecialSignalHandlerFn;
RemoveSpecialSignalHandlerFn;
local:
*;
};

0 comments on commit d8cc12b

Please sign in to comment.