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

Add additional context tests. #157

Merged
merged 1 commit into from
Jul 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
70 changes: 53 additions & 17 deletions javatests/com/jnibind/test/ContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,56 @@ public static void doShutDown() {

@Test
public void testGlobalObjectsPersistAcrossJniOverloads() {
long native_context = CreateNativeContextObject(555);
assertThat(QueryNativeObject(native_context).intVal1).isEqualTo(555);
assertThat(QueryNativeObject(native_context).intVal1).isEqualTo(555);
assertThat(QueryNativeObject(native_context).intVal1).isEqualTo(555);
assertThat(QueryNativeObject(native_context).intVal1).isEqualTo(555);
assertThat(ExtractNativeObject(native_context).intVal1).isEqualTo(555);
assertThat(QueryNativeObject(native_context)).isEqualTo(null);
assertThat(QueryNativeObject(native_context)).isEqualTo(null);
long nativeContext = nativeCreateContext(555);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(555);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(555);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(555);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(555);
assertThat(nativeExtractObject(nativeContext).intVal1).isEqualTo(555);
assertThat(nativeQueryObject(nativeContext)).isEqualTo(null);
assertThat(nativeQueryObject(nativeContext)).isEqualTo(null);
}

@Test
public void testGlobalObjectsPersistAcrossJniOverloads2() {
assertThat(CreateNativeContextObjectSetValToSum(5, 7).intVal1).isEqualTo(12);
assertThat(nativeCreateContextSetValToSum(5, 7).intVal1).isEqualTo(12);
}

@Test
public void testGlobalObjectsBeDestroyed() {
long native_context = CreateNativeContextObject(9876);
assertThat(QueryNativeObject(native_context).intVal1).isEqualTo(9876);
DestroyNativeContext(native_context);
long nativeContext = nativeCreateContext(9876);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(9876);
nativeDestroyContext(nativeContext);
}

@Test
public void testObjectsOriginatedFromJavaPersistWhenPromotedToGlobal() {
ObjectTestHelper objectTestHelper = new ObjectTestHelper(9876);
long nativeContext = nativeCreateContextWithPromotion(objectTestHelper);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(9876);
objectTestHelper.intVal1 = 1234;
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(1234);

// Despite the object being deleted here, the native object pins.
objectTestHelper = null;
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(1234);

nativeDestroyContext(nativeContext);
}

@Test
public void testObjectsOriginatedFromJavaPersistWhenCopied() {
ObjectTestHelper objectTestHelper = new ObjectTestHelper(9876);
long nativeContext = nativeCreateContextWithCopy(objectTestHelper);
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(9876);
objectTestHelper.intVal1 = 1234;
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(1234);

// Despite the object being deleted here, the native object pins.
objectTestHelper = null;
assertThat(nativeQueryObject(nativeContext).intVal1).isEqualTo(1234);

nativeDestroyContext(nativeContext);
}

// Some kind of "initial call". This test suite doesn't override JNIOnload in order to emulate
Expand All @@ -74,18 +104,24 @@ public void testGlobalObjectsBeDestroyed() {

// Causes native code to create an object that will be stored in native code and returned on a
// subsequent call. This can only be done with global objects and not local objects.
native long CreateNativeContextObject(int val);
native long nativeCreateContext(int val);

// Takes the passed in context and stores copy in the context, returned as long.
native long nativeCreateContextWithPromotion(ObjectTestHelper val);

// Takes the passed in context and stores copy in the context, returned as long.
native long nativeCreateContextWithCopy(ObjectTestHelper val);

// Returns an ObjectTestHelper with intVal1 set to the sum of the vals.
native ObjectTestHelper CreateNativeContextObjectSetValToSum(int val1, int val2);
native ObjectTestHelper nativeCreateContextSetValToSum(int val1, int val2);

// Returns a handle to a global object held within the inner native context.
native ObjectTestHelper QueryNativeObject(long context);
native ObjectTestHelper nativeQueryObject(long context);

// Returns the handle to the native context, but simultaneously releases it in the process.
native ObjectTestHelper ExtractNativeObject(long context);
native ObjectTestHelper nativeExtractObject(long context);

// Destroys the entire native context possibly releasing the contained global object.
// This would be representative of when an app would be shutting down.
native void DestroyNativeContext(long context);
native void nativeDestroyContext(long context);
}
37 changes: 27 additions & 10 deletions javatests/com/jnibind/test/context_test_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

namespace {

using ::jni::CreateCopy;
using ::jni::GlobalObject;
using ::jni::PromoteToGlobal;

// A struct that could represent context to be maintained across multiple native
// JNI invocations. Only global objects can be held in this way, local objects
Expand Down Expand Up @@ -50,38 +52,53 @@ JNIEXPORT void JNICALL Java_com_jnibind_test_ContextTest_DoSetup(JNIEnv* env,
jvm.reset(new jni::JvmRef<jni::kDefaultJvm>{env});
}

JNIEXPORT jlong JNICALL
Java_com_jnibind_test_ContextTest_CreateNativeContextObject(JNIEnv* env, jclass,
jint val) {
JNIEXPORT jlong JNICALL Java_com_jnibind_test_ContextTest_nativeCreateContext(
JNIEnv* env, jclass, jint val) {
auto* ctx_struct = new ContextStruct{GlobalObject<kObjectTestHelperClass>{}};
ctx_struct->obj["intVal1"].Set(jint{val});

return reinterpret_cast<jlong>(ctx_struct);
}

JNIEXPORT jlong JNICALL
Java_com_jnibind_test_ContextTest_nativeCreateContextWithPromotion(
JNIEnv* env, jclass, jobject val) {
return reinterpret_cast<jlong>(new ContextStruct{
GlobalObject<kObjectTestHelperClass>{PromoteToGlobal{}, val}});
}

JNIEXPORT jlong JNICALL
Java_com_jnibind_test_ContextTest_nativeCreateContextWithCopy(JNIEnv* env,
jclass,
jobject val) {
return reinterpret_cast<jlong>(new ContextStruct{
.obj = GlobalObject<kObjectTestHelperClass>{CreateCopy{}, val}});
}

JNIEXPORT jobject JNICALL
Java_com_jnibind_test_ContextTest_CreateNativeContextObjectSetValToSum(
JNIEnv* env, jclass, jint val1, jint val2) {
Java_com_jnibind_test_ContextTest_nativeCreateContextSetValToSum(JNIEnv* env,
jclass,
jint val1,
jint val2) {
// Creates a temporary test helper, calls its member method, and releases the
// returned object across the C API boundary (then destroys the temporary).
return jni::LocalObject<kObjectTestHelperClass>{}(
"returnNewObjectWithFieldSetToSum", val1, val2)
.Release();
}

JNIEXPORT jobject JNICALL Java_com_jnibind_test_ContextTest_QueryNativeObject(
JNIEXPORT jobject JNICALL Java_com_jnibind_test_ContextTest_nativeQueryObject(
JNIEnv* env, jclass, void* ctx_void_ptr) {
ContextStruct* ctx_struct = static_cast<ContextStruct*>(ctx_void_ptr);
return jobject{ctx_struct->obj};
}

JNIEXPORT jobject JNICALL Java_com_jnibind_test_ContextTest_ExtractNativeObject(
JNIEXPORT jobject JNICALL Java_com_jnibind_test_ContextTest_nativeExtractObject(
JNIEnv* env, jclass, void* ctx_void_ptr) {
ContextStruct* ctx_struct = static_cast<ContextStruct*>(ctx_void_ptr);
return ctx_struct->obj.Release();
return static_cast<ContextStruct*>(ctx_void_ptr)->obj.Release();
}

JNIEXPORT void JNICALL Java_com_jnibind_test_ContextTest_DestroyNativeContext(
JNIEXPORT void JNICALL Java_com_jnibind_test_ContextTest_nativeDestroyContext(
JNIEnv* env, jclass, void* ctx_void_ptr) {
delete static_cast<ContextStruct*>(ctx_void_ptr);
}
Expand Down