Skip to content

Commit

Permalink
Add additional context tests.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 544811587
  • Loading branch information
jwhpryor authored and copybara-github committed Jul 1, 2023
1 parent 8c26f2e commit 085f500
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 27 deletions.
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

0 comments on commit 085f500

Please sign in to comment.