diff options
author | zmiao <miao.zhao@mapbox.com> | 2019-11-03 21:49:06 +0200 |
---|---|---|
committer | zmiao <miao.zhao@mapbox.com> | 2019-11-03 21:49:06 +0200 |
commit | e975f7ceebb7c8223896c4cfb18efa1b089beea6 (patch) | |
tree | dc9d43f5595617e3ba12448e0815913ea77c453a | |
parent | 5b38cfee18800cbb3c6a3186882744592662c3d6 (diff) |
[render-test] Wrap test resources inside app
-rw-r--r-- | next/render-test/CMakeLists.txt | 8 | ||||
-rw-r--r-- | platform/android/src/test/render_test_runner.cpp | 137 | ||||
-rw-r--r-- | render-test/android-manifest.json | 8 | ||||
-rw-r--r-- | render-test/android/app/build.gradle | 7 | ||||
-rw-r--r-- | render-test/android/app/src/main/assets/res.zip | bin | 0 -> 51528216 bytes | |||
-rw-r--r-- | render-test/render_test.cpp | 10 |
6 files changed, 152 insertions, 18 deletions
diff --git a/next/render-test/CMakeLists.txt b/next/render-test/CMakeLists.txt index fa4bb0d61..0fef727c3 100644 --- a/next/render-test/CMakeLists.txt +++ b/next/render-test/CMakeLists.txt @@ -38,12 +38,8 @@ include(${PROJECT_SOURCE_DIR}/vendor/boost.cmake) target_link_libraries( mbgl-render-test - PRIVATE - Mapbox::Base::Extras::args - Mapbox::Base::Extras::filesystem - Mapbox::Base::pixelmatch-cpp - mbgl-vendor-boost - PUBLIC mbgl-core + PRIVATE Mapbox::Base::Extras::args Mapbox::Base::pixelmatch-cpp + PUBLIC mbgl-core mbgl-vendor-boost Mapbox::Base::Extras::filesystem ) if(CMAKE_SYSTEM_NAME STREQUAL Android) diff --git a/platform/android/src/test/render_test_runner.cpp b/platform/android/src/test/render_test_runner.cpp index d4554aa9d..83e0a11c9 100644 --- a/platform/android/src/test/render_test_runner.cpp +++ b/platform/android/src/test/render_test_runner.cpp @@ -1,15 +1,16 @@ #include <android_native_app_glue.h> +#include <ghc/filesystem.hpp> #include <mbgl/render_test.hpp> +#include <mbgl/util/logging.hpp> + +#include <android/asset_manager.h> +#include <android/log.h> + #include "jni.hpp" -#include "logger.hpp" #include <string> #include <vector> -#include <mbgl/util/logging.hpp> - -#include <android/log.h> - namespace mbgl { namespace { @@ -41,17 +42,139 @@ void Log::platformRecord(EventSeverity severity, const std::string& msg) { } // namespace mbgl +void copyFile(AAssetManager* assetManager, const std::string& filePath, const std::string& fileName) { + if (ghc::filesystem::exists(filePath)) { + mbgl::Log::Warning(mbgl::Event::General, "File '%s' already exists", filePath.c_str()); + } else { + AAsset* fileAsset = AAssetManager_open(assetManager, fileName.c_str(), AASSET_MODE_BUFFER); + const void* fileData = AAsset_getBuffer(fileAsset); + const off_t fileLen = AAsset_getLength(fileAsset); + + FILE* newFile = std::fopen(filePath.c_str(), "w+"); + if (NULL == newFile) { + mbgl::Log::Warning(mbgl::Event::General, "Failed to create new file entry %s", fileName.c_str()); + } else { + auto res = std::fwrite(fileData, sizeof(char), fileLen, newFile); + if (fileLen != res) { + mbgl::Log::Warning( + mbgl::Event::General, "Failed to generate file entry %s from assets", fileName.c_str()); + } + } + std::fclose(newFile); + AAsset_close(fileAsset); + } +} + +std::string jstring2string(JNIEnv* env, jstring jStr) { + if (!jStr) { + return ""; + } + + const jclass stringClass = env->GetObjectClass(jStr); + const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); + const jbyteArray stringJbytes = (jbyteArray)env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8")); + + size_t length = (size_t)env->GetArrayLength(stringJbytes); + jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); + + std::string ret = std::string((char*)pBytes, length); + env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); + + env->DeleteLocalRef(stringJbytes); + env->DeleteLocalRef(stringClass); + return ret; +} + void android_main(struct android_app* app) { mbgl::android::theJVM = app->activity->vm; - JNIEnv* env; + JNIEnv* env = nullptr; app->activity->vm->AttachCurrentThread(&env, NULL); + const char* storage_chars = app->activity->internalDataPath; + std::string storagePath(storage_chars); + + std::string zipFile = storagePath + "/res.zip"; + + AAssetManager* assetManager = app->activity->assetManager; + copyFile(assetManager, zipFile, "res.zip"); + + jclass fileInputStream = env->FindClass("java/io/FileInputStream"); + jmethodID finCtor = env->GetMethodID(fileInputStream, "<init>", "(Ljava/lang/String;)V"); + + jclass fileOutputStream = env->FindClass("java/io/FileOutputStream"); + jmethodID foutCtor = env->GetMethodID(fileOutputStream, "<init>", "(Ljava/io/File;)V"); + jmethodID foutClose = env->GetMethodID(fileOutputStream, "close", "()V"); + jmethodID foutWrite = env->GetMethodID(fileOutputStream, "write", "([BII)V"); + + jclass zipInputStream = env->FindClass("java/util/zip/ZipInputStream"); + jmethodID zinCtor = env->GetMethodID(zipInputStream, "<init>", "(Ljava/io/InputStream;)V"); + jmethodID zinGetNextEntry = env->GetMethodID(zipInputStream, "getNextEntry", "()Ljava/util/zip/ZipEntry;"); + jmethodID zinRead = env->GetMethodID(zipInputStream, "read", "([B)I"); + jmethodID zinCloseEntry = env->GetMethodID(zipInputStream, "closeEntry", "()V"); - std::vector<std::string> arguments = {"mbgl-render-test-runner", "-p", "/sdcard/render-test/android-manifest.json"}; + jclass zipEntry = env->FindClass("java/util/zip/ZipEntry"); + jmethodID getName = env->GetMethodID(zipEntry, "getName", "()Ljava/lang/String;"); + jmethodID zipIsDirectory = env->GetMethodID(zipEntry, "isDirectory", "()Z"); + + jclass fileClass = env->FindClass("java/io/File"); + jmethodID fileCtor = env->GetMethodID(fileClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V"); + jmethodID fileIsDirectory = env->GetMethodID(fileClass, "isDirectory", "()Z"); + jmethodID exists = env->GetMethodID(fileClass, "exists", "()Z"); + jmethodID createNewFile = env->GetMethodID(fileClass, "createNewFile", "()Z"); + jmethodID fileGetName = env->GetMethodID(fileClass, "getName", "()Ljava/lang/String;"); + + // Upzip the resource folder to destination path + jstring destination = env->NewStringUTF(storage_chars); + jstring jstr = env->NewStringUTF(zipFile.c_str()); + jobject fin = env->NewObject(fileInputStream, finCtor, jstr); + jobject zin = env->NewObject(zipInputStream, zinCtor, fin); + jobject ze = NULL; + while ((ze = env->CallObjectMethod(zin, zinGetNextEntry)) != NULL) { + jstring dir = (jstring)env->CallObjectMethod(ze, getName); + std::string name = jstring2string(env, dir); + bool ok = env->CallBooleanMethod(ze, zipIsDirectory); + + jobject f = env->NewObject(fileClass, fileCtor, destination, dir); + if (ok) { + if (!(env->CallBooleanMethod(f, fileIsDirectory))) { + jmethodID mkdirs = env->GetMethodID(fileClass, "mkdirs", "()Z"); + jboolean success = (env->CallBooleanMethod(f, mkdirs)); + std::string fileName = jstring2string(env, (jstring)env->CallObjectMethod(f, fileGetName)); + if (!success) { + mbgl::Log::Warning( + mbgl::Event::General, "Failed to create folder entry %s from zip", fileName.c_str()); + } + } + } else { + if (!(env->CallBooleanMethod(f, exists))) { + jboolean success = env->CallBooleanMethod(f, createNewFile); + std::string fileName = jstring2string(env, (jstring)env->CallObjectMethod(f, fileGetName)); + if (!success) { + mbgl::Log::Warning( + mbgl::Event::General, "Failed to create folder entry %s from zip", fileName.c_str()); + continue; + } + jobject fout = env->NewObject(fileOutputStream, foutCtor, f); + jbyteArray jBuff = env->NewByteArray(2048); + int count; + while ((count = env->CallIntMethod(zin, zinRead, jBuff)) != -1) { + env->CallVoidMethod(fout, foutWrite, jBuff, 0, count); + } + env->CallVoidMethod(zin, zinCloseEntry); + env->CallVoidMethod(fout, foutClose); + env->DeleteLocalRef(jBuff); + } + } + } + + std::string configFile = storagePath + "/android-manifest.json"; + + std::vector<std::string> arguments = {"mbgl-render-test-runner", "-p", configFile}; std::vector<char*> argv; for (const auto& arg : arguments) { argv.push_back((char*)arg.data()); } argv.push_back(nullptr); (void)mbgl::runRenderTests(argv.size() - 1, argv.data()); + app->activity->vm->DetachCurrentThread(); }
\ No newline at end of file diff --git a/render-test/android-manifest.json b/render-test/android-manifest.json index 56223d475..9cd9d62a7 100644 --- a/render-test/android-manifest.json +++ b/render-test/android-manifest.json @@ -1,7 +1,7 @@ { - "base_test_path":"mapbox-gl-js/test/integration", - "expectation_paths":["render-test/expected/render-tests"], - "ignore_paths":["platform/node/test/ignores.json", "render-test/linux-ignores.json", "render-test/tests/should-fail.json"], + "base_test_path":".", + "expectation_paths":[], + "ignore_paths":["ignores/ignores.json", "ignores/linux-ignores.json"], "vendor_path":"vendor", - "asset_path": "mapbox-gl-js/test/integration" + "asset_path": "." }
\ No newline at end of file diff --git a/render-test/android/app/build.gradle b/render-test/android/app/build.gradle index 60609e3ba..d5115e8aa 100644 --- a/render-test/android/app/build.gradle +++ b/render-test/android/app/build.gradle @@ -14,6 +14,11 @@ android { targets 'mbgl-render-test-runner' } } + ndk { + // Tells Gradle to build outputs for the following ABIs and package + // them into your APK. + abiFilters 'arm64-v8a' + } } externalNativeBuild { cmake { @@ -26,4 +31,6 @@ android { dependencies { implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-beta01' + androidTestImplementation 'androidx.test:rules:1.2.0-beta01' } diff --git a/render-test/android/app/src/main/assets/res.zip b/render-test/android/app/src/main/assets/res.zip Binary files differnew file mode 100644 index 000000000..533c4f7fc --- /dev/null +++ b/render-test/android/app/src/main/assets/res.zip diff --git a/render-test/render_test.cpp b/render-test/render_test.cpp index 38d6c15f3..5ea120252 100644 --- a/render-test/render_test.cpp +++ b/render-test/render_test.cpp @@ -182,24 +182,27 @@ int runRenderTests(int argc, char** argv) { status = "passed"; color = "green"; stats.passedTests++; + mbgl::Log::Warning(mbgl::Event::General, "* passed %s" ANSI_COLOR_RESET "\n", id.c_str()); printf(ANSI_COLOR_GREEN "* passed %s" ANSI_COLOR_RESET "\n", id.c_str()); } else if (errored) { status = "errored"; color = "red"; stats.erroredTests++; + mbgl::Log::Warning(mbgl::Event::General, "* errored %s" ANSI_COLOR_RESET "\n", id.c_str()); printf(ANSI_COLOR_RED "* errored %s" ANSI_COLOR_RESET "\n", id.c_str()); printf(ANSI_COLOR_RED "* error: %s" ANSI_COLOR_RESET "\n", metadata.errorMessage.c_str()); } else { status = "failed"; color = "red"; stats.failedTests++; + mbgl::Log::Warning(mbgl::Event::General, "* failed %s" ANSI_COLOR_RESET "\n", id.c_str()); printf(ANSI_COLOR_RED "* failed %s" ANSI_COLOR_RESET "\n", id.c_str()); } } metadatas.push_back(std::move(metadata)); } - const auto& testRootPath = manifest.getManifestPath(); +const auto& testRootPath = manifest.getManifestPath(); const auto resultPath = testRootPath + "/" + (testNames.empty() ? "render-tests" : testNames.front()) + "_index.html"; std::string resultsHTML = createResultPage(stats, metadatas, shuffle, seed); @@ -209,18 +212,23 @@ int runRenderTests(int argc, char** argv) { stats.erroredTests + stats.failedTests + stats.ignoreFailedTests + stats.ignorePassedTests + stats.passedTests; if (stats.passedTests) { + mbgl::Log::Warning(mbgl::Event::General, "%u passed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.passedTests, 100.0 * stats.passedTests / count); printf(ANSI_COLOR_GREEN "%u passed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.passedTests, 100.0 * stats.passedTests / count); } if (stats.ignorePassedTests) { + mbgl::Log::Warning(mbgl::Event::General,"%u passed but were ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignorePassedTests, 100.0 * stats.ignorePassedTests / count); printf(ANSI_COLOR_YELLOW "%u passed but were ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignorePassedTests, 100.0 * stats.ignorePassedTests / count); } if (stats.ignoreFailedTests) { + mbgl::Log::Warning(mbgl::Event::General,"%u ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignoreFailedTests, 100.0 * stats.ignoreFailedTests / count); printf(ANSI_COLOR_LIGHT_GRAY "%u ignored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.ignoreFailedTests, 100.0 * stats.ignoreFailedTests / count); } if (stats.failedTests) { + mbgl::Log::Warning(mbgl::Event::General, "%u failed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.failedTests, 100.0 * stats.failedTests / count); printf(ANSI_COLOR_RED "%u failed (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.failedTests, 100.0 * stats.failedTests / count); } if (stats.erroredTests) { + mbgl::Log::Warning(mbgl::Event::General,"%u errored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.erroredTests, 100.0 * stats.erroredTests / count); printf(ANSI_COLOR_RED "%u errored (%.1lf%%)" ANSI_COLOR_RESET "\n", stats.erroredTests, 100.0 * stats.erroredTests / count); } |