Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google tests framework for UnitTests #1277

Merged
merged 59 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
fe3cedb
Google tests framework for UnitTesting
CedricGuillemet Aug 7, 2023
81ce56a
includes, android tests
CedricGuillemet Aug 7, 2023
7de3ebd
test exit code
CedricGuillemet Aug 7, 2023
d84daee
npm android
CedricGuillemet Aug 7, 2023
4232bfa
bgfx noop
CedricGuillemet Aug 7, 2023
f21cba0
console callback, missing .js for android
CedricGuillemet Aug 7, 2023
df3cea0
removed comment
CedricGuillemet Aug 7, 2023
6e3fa54
android logging
CedricGuillemet Aug 7, 2023
486157e
close stdout
CedricGuillemet Aug 7, 2023
3a77d0c
flush stdout
CedricGuillemet Aug 7, 2023
d77202c
close pipes
CedricGuillemet Aug 7, 2023
95d2796
yet another log attachment
CedricGuillemet Aug 7, 2023
0524d5a
logger...
CedricGuillemet Aug 7, 2023
4b391b1
no stop
CedricGuillemet Aug 7, 2023
ad3f645
no thread
CedricGuillemet Aug 7, 2023
ad98680
pfd
CedricGuillemet Aug 7, 2023
58d3998
pfd
CedricGuillemet Aug 7, 2023
b173c0c
vbuf
CedricGuillemet Aug 7, 2023
cc619b9
vbuf
CedricGuillemet Aug 7, 2023
448f03d
descriptors
CedricGuillemet Aug 7, 2023
f1b5fd8
log
CedricGuillemet Aug 8, 2023
5deff08
timeout
CedricGuillemet Aug 8, 2023
7ff626d
nop
CedricGuillemet Aug 8, 2023
2582c4c
disable android tests for now
CedricGuillemet Aug 8, 2023
c75c6bb
life cycle test
CedricGuillemet Aug 8, 2023
914361e
inspector test
CedricGuillemet Aug 8, 2023
44d9e31
disable android tests
CedricGuillemet Aug 8, 2023
e7bd7a1
JS test
CedricGuillemet Aug 8, 2023
16cd56d
disable lifecycle test
CedricGuillemet Aug 8, 2023
419c0cd
fix capture
CedricGuillemet Aug 8, 2023
ebac593
disable js scripts
CedricGuillemet Aug 8, 2023
7899764
revert
CedricGuillemet Aug 8, 2023
2f8c471
revert jobs
CedricGuillemet Aug 8, 2023
3b1c556
nop
CedricGuillemet Aug 8, 2023
c6ca460
Update Apps/UnitTests/Android/app/src/main/res/values/strings.xml
CedricGuillemet Sep 5, 2023
c1fc566
Update Apps/UnitTests/Shared/Tests.h
CedricGuillemet Sep 5, 2023
bd28c7c
PR feedback and testing with v8inspector crash fix
CedricGuillemet Sep 5, 2023
b4e0895
Merge branch 'master' of https://github.com/BabylonJS/BabylonNative i…
CedricGuillemet Sep 5, 2023
f0f452c
up jsr
CedricGuillemet Sep 5, 2023
3a256df
absolute path
CedricGuillemet Sep 5, 2023
271921a
hash
CedricGuillemet Sep 5, 2023
4f274ad
up jsr
CedricGuillemet Sep 5, 2023
51051c1
hash
CedricGuillemet Sep 5, 2023
23ad135
Update Apps/UnitTests/Android/app/src/main/cpp/CMakeLists.txt
CedricGuillemet Sep 6, 2023
8f8a40f
disable CPP LifeCycle tests for now
CedricGuillemet Sep 19, 2023
4e75cff
Merge branch 'master' of https://github.com/babylonJS/BabylonNative i…
CedricGuillemet Sep 19, 2023
8a9e804
JSR host
CedricGuillemet Sep 19, 2023
af277d9
bgfx render type
CedricGuillemet Sep 19, 2023
9abf136
render type
CedricGuillemet Sep 19, 2023
d295d55
Disable Android Tests
CedricGuillemet Sep 19, 2023
6a3a64b
Update Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
CedricGuillemet Sep 20, 2023
57bc2a2
Update Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
CedricGuillemet Sep 20, 2023
db9eaba
Update Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
CedricGuillemet Sep 20, 2023
31d9c10
Update Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
CedricGuillemet Sep 20, 2023
f565e61
Update Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
CedricGuillemet Sep 20, 2023
6595193
Update Core/Graphics/Source/DeviceImpl.h
CedricGuillemet Sep 20, 2023
99aef2e
gtest_force_shared_crt infos
CedricGuillemet Sep 20, 2023
8538d9c
win32 check for gtest
CedricGuillemet Sep 20, 2023
4546452
better win32 check
CedricGuillemet Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/jobs/android_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
parameters:
name: ''
vmImage: ''
JSEngine: ''
macOSCodename: ''

jobs:
- job: ${{ parameters.name }}
timeoutInMinutes: 45
pool:
vmImage: ${{ parameters.vmImage }}

steps:
- script: |
git submodule update --init --recursive
displayName: 'Checkout dependencies'
- template: cmake.yml
parameters:
vmImage: ${{ parameters.vmImage }}

- script: |
echo Install Android image
echo 'y' | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-27;default;x86_64'
echo 'y' | $ANDROID_HOME/tools/bin/sdkmanager --licenses
echo Create AVD
$ANDROID_HOME/tools/bin/avdmanager create avd -n Pixel_API_27 -d pixel -k 'system-images;android-27;default;x86_64'
displayName: 'Install Android Emulator'
- script: |
echo Start emulator
nohup $ANDROID_HOME/emulator/emulator -avd Pixel_API_27 -gpu host -no-window 2>&1 &
echo Wait for emulator
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do echo '.'; sleep 1; done'
$ANDROID_HOME/platform-tools/adb devices
displayName: 'Start Android Emulator'

- task: Gradle@3
inputs:
gradleWrapperFile: 'Apps/UnitTests/Android/gradlew'
workingDirectory: 'Apps/UnitTests/Android'
options: '-PabiFilters=x86_64 -PjsEngine=${{parameters.jsEngine}}'
tasks: 'connectedAndroidTest'
jdkVersionOption: 1.11
displayName: 'Run Connected Android Test'

- script: |
export results=$(find ./app/build/outputs/androidTest-results -name "*.txt")
echo cat "$results"
cat "$results"
workingDirectory: 'Apps/UnitTests/Android'
condition: succeededOrFailed()
displayName: 'Dump logcat from Test Results'

- task: PublishBuildArtifacts@1
inputs:
pathToPublish: 'Apps/UnitTests/Android/app/build/outputs/androidTest-results/connected'
artifactName: 'AndroidTestResults_${{parameters.jsEngine}}'
condition: succeededOrFailed()
displayName: 'Publish Test Results'
10 changes: 10 additions & 0 deletions Apps/UnitTests/Android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.iml
.gradle/
.idea/
local.properties

app/.cxx/
app/build/
app/src/main/assets

build/
116 changes: 116 additions & 0 deletions Apps/UnitTests/Android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
plugins {
id 'com.android.application'
}

def jsEngine = "V8"
if (project.hasProperty("jsEngine")) {
jsEngine = project.property("jsEngine")
}

configurations { natives }

android {
namespace 'com.babylonnative.unittests'
compileSdk 33
ndkVersion = "21.4.7075529"

defaultConfig {
applicationId "com.babylonnative.unittests"
minSdk 21
targetSdk 33
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

externalNativeBuild {
cmake {
arguments (
"-DANDROID_STL=c++_shared",
"-DNAPI_JAVASCRIPT_ENGINE=${jsEngine}",
"-DJSRUNTIMEHOST_CORE_APPRUNTIME_V8_INSPECTOR=ON",
)
}
}

if (project.hasProperty("abiFilters")) {
ndk {
abiFilters project.getProperty("abiFilters")
}
}
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
buildStagingDirectory '../../../../Build/Android'
version '3.22.1+'
}
}
buildFeatures {
viewBinding true
}
}

dependencies {
implementation 'com.google.ar:core:1.16.0'
natives 'com.google.ar:core:1.16.0'
implementation 'androidx.appcompat:appcompat:1.6.0'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation group: 'org.java-websocket', name: 'Java-WebSocket', version: '1.5.3'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

task copyScripts {
doLast {
// run copy at execution phase because npm command is not done at configuration phase
copy
{
from "../../../node_modules/chai"
include "chai.js"
into 'src/main/assets/Scripts'
}
copy
{
from "../../../node_modules/mocha"
include "mocha.js"
into 'src/main/assets/Scripts'
}
copy
{
from "../../../node_modules/babylonjs"
include "babylon.max.js"
into 'src/main/assets/Scripts'
}
copy
{
from "../../../node_modules/babylonjs-materials"
include "babylonjs.materials.js"
into 'src/main/assets/Scripts'
}
}
}

// Run copyScripts task after CMake external build
// And make sure merging assets into output is performed after the scripts copy
tasks.whenTaskAdded { task ->
if (task.name == 'mergeDebugNativeLibs') {
task.finalizedBy(copyScripts)
}
if (task.name == 'mergeDebugAssets') {
task.dependsOn(copyScripts)
}
}
21 changes: 21 additions & 0 deletions Apps/UnitTests/Android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.babylonnative.unittests;

import android.content.Context;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class Main {
@Test
public void javaScriptTests() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.babylonnative.unittests", appContext.getPackageName());

assertEquals(0, Native.javaScriptTests(appContext));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.babylonnative.unittests;

import android.content.Context;

public class Native {
// JNI interface
static {
System.loadLibrary("UnitTestsJNI");
}

public static native int javaScriptTests(Context context);
}
8 changes: 8 additions & 0 deletions Apps/UnitTests/Android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application android:label="@string/app_name" />

<uses-permission android:name="android.permission.INTERNET" />

</manifest>
43 changes: 43 additions & 0 deletions Apps/UnitTests/Android/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.18)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(UnitTestsJNI)

get_filename_component(UNIT_TESTS_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../.." ABSOLUTE)
get_filename_component(REPO_ROOT_DIR "${UNIT_TESTS_DIR}/../.." ABSOLUTE)

set(JSRUNTIMEHOST_TESTS OFF) # Turn off the tests folder for Android Studio path
add_subdirectory(${REPO_ROOT_DIR} "${CMAKE_CURRENT_BINARY_DIR}/BabylonNative")

get_filename_component(APPS_DIR "${UNIT_TESTS_DIR}/.." ABSOLUTE)
npm(install "${APPS_DIR}" "Apps" "--silent")

add_library(UnitTestsJNI SHARED
JNI.cpp
${UNIT_TESTS_DIR}/Shared/Tests.h)
target_compile_definitions(UnitTestsJNI PRIVATE JSRUNTIMEHOST_PLATFORM="${JSRUNTIMEHOST_PLATFORM}")

target_include_directories(UnitTestsJNI
PRIVATE ${UNIT_TESTS_DIR})

target_link_libraries(UnitTestsJNI
PRIVATE GLESv3
PRIVATE android
PRIVATE EGL
PRIVATE log
PRIVATE -lz
PRIVATE AndroidExtensions
PRIVATE AppRuntime
PRIVATE Canvas
PRIVATE Console
PRIVATE GraphicsDevice
PRIVATE NativeCamera
PRIVATE NativeEngine
PRIVATE NativeInput
PRIVATE NativeOptimizations
PRIVATE ScriptLoader
PRIVATE XMLHttpRequest
PRIVATE gtest_main
PRIVATE Window)
72 changes: 72 additions & 0 deletions Apps/UnitTests/Android/app/src/main/cpp/JNI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "gtest/gtest.h"
#include <jni.h>
#include <Android/log.h>
#include <AndroidExtensions/Globals.h>
#include <AndroidExtensions/JavaWrappers.h>
#include <atomic>
#include <Shared/Tests.h>

namespace
{
int pfd[2];
int fd_saved[2];
}
void* thread_func(void*)
{
ssize_t rdsz;
char buf[128];
while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0)
{
if (buf[rdsz - 1] == '\n') --rdsz;
buf[rdsz] = 0;
__android_log_write(ANDROID_LOG_DEBUG, "UnitTests", buf);
}
__android_log_write(ANDROID_LOG_DEBUG, "UnitTests", "Logger shutdown");
return 0;
}

void start_logger()
{
pthread_t thr;

// make stdout line-buffered and stderr unbuffered
fd_saved[0] = setvbuf(stdout, 0, _IOLBF, 0);
fd_saved[1] = setvbuf(stderr, 0, _IONBF, 0);

// create the pipe and redirect stdout and stderr
pipe(pfd);
dup2(pfd[1], 1);
dup2(pfd[1], 2);

// spawn the logging thread
if (pthread_create(&thr, 0, thread_func, 0) == -1)
{
return;
}
pthread_detach(thr);
}

void stop_logger()
{
close(pfd[1]);
close(pfd[0]);
setvbuf(stdout, NULL, fd_saved[0], 0);
setvbuf(stderr, NULL, fd_saved[1], 0);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_babylonnative_unittests_Native_javaScriptTests(JNIEnv* env, jclass clazz, jobject context) {
JavaVM* javaVM{};
if (env->GetJavaVM(&javaVM) != JNI_OK)
{
throw std::runtime_error{"Failed to get Java VM"};
}

start_logger();
CedricGuillemet marked this conversation as resolved.
Show resolved Hide resolved

android::global::Initialize(javaVM, context);
auto testResult = Run();

stop_logger();
return testResult;
}
3 changes: 3 additions & 0 deletions Apps/UnitTests/Android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">BabylonNative UnitTests</string>
</resources>
5 changes: 5 additions & 0 deletions Apps/UnitTests/Android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
}
Loading