From e40ba296e64b3c4f0d6092428bebe8b7ca486e24 Mon Sep 17 00:00:00 2001 From: Alexander Schuetz Date: Tue, 17 Sep 2024 02:02:32 +0200 Subject: [PATCH] increase test coverage to 82% --- tests/attach_and_die.rs | 79 ++++++++++++++++++++++++++++++++++++ tests/bad_version_launch.rs | 19 +++++++++ tests/create_bad_argument.rs | 18 ++++++++ tests/launch_prop.rs | 27 ++++++++++++ 4 files changed, 143 insertions(+) create mode 100644 tests/attach_and_die.rs create mode 100644 tests/bad_version_launch.rs create mode 100644 tests/create_bad_argument.rs create mode 100644 tests/launch_prop.rs diff --git a/tests/attach_and_die.rs b/tests/attach_and_die.rs new file mode 100644 index 0000000..72858ea --- /dev/null +++ b/tests/attach_and_die.rs @@ -0,0 +1,79 @@ +#[cfg(feature = "loadjvm")] +pub mod test { + use jni_simple::*; + use std::ptr::null_mut; + use std::sync::{Arc, Condvar, Mutex}; + use std::time::Duration; + + #[test] + fn test() { + unsafe { + load_jvm_from_java_home().expect("failed to load jvm"); + let args: Vec = vec![]; + let (vm, _env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args).expect("failed to create java VM"); + + let vm_clone = vm.clone(); + std::thread::spawn(move || { + assert_eq!(JNI_EDETACHED, vm_clone.GetEnv(JNI_VERSION_1_8).unwrap_err()); + let _env = vm_clone.AttachCurrentThread_str(JNI_VERSION_1_8, None, null_mut()).unwrap(); + assert!(vm_clone.GetEnv(JNI_VERSION_1_8).is_ok()); + let _env = vm_clone.AttachCurrentThread_str(JNI_VERSION_1_8, None, null_mut()).unwrap(); + assert_eq!(JNI_OK, vm_clone.DetachCurrentThread()); + assert_eq!(JNI_EDETACHED, vm_clone.GetEnv(JNI_VERSION_1_8).unwrap_err()); + let env = vm_clone.AttachCurrentThread_str(JNI_VERSION_1_8, Some("HelloWorld"), null_mut()).unwrap(); + let n = env.FindClass_str("java/lang/Thread"); + let gt = env.GetStaticMethodID_str(n, "currentThread", "()Ljava/lang/Thread;"); + let gn = env.GetMethodID_str(n, "getName", "()Ljava/lang/String;"); + let thread = env.CallStaticObjectMethod0(n, gt); + let thread_name_j = env.CallObjectMethod0(thread, gn); + let jn = env.GetStringUTFChars_as_string(thread_name_j).unwrap(); + assert_eq!("HelloWorld", jn.as_str()); + env.DeleteLocalRef(thread_name_j); + env.DeleteLocalRef(thread); + env.DeleteLocalRef(n); + assert_eq!(JNI_OK, vm_clone.DetachCurrentThread()); + assert_eq!(JNI_OK, vm_clone.DetachCurrentThread()); + }).join().unwrap(); + + let vm_clone = vm.clone(); + + let l1 = Arc::new((Mutex::new(()), Condvar::new(), Condvar::new())); + let l2 = l1.clone(); + let l3 = l2.clone(); + + + let guard = l1.0.lock().unwrap(); + + + std::thread::spawn(move || { + let guard = l2.0.lock().unwrap(); + let _env = vm_clone.AttachCurrentThreadAsDaemon_str(JNI_VERSION_1_8, None, null_mut()).unwrap(); + assert!(vm_clone.GetEnv(JNI_VERSION_1_8).is_ok()); + l2.1.notify_all(); + let _guard = l2.1.wait(guard).unwrap(); + }); + + let guard = l1.1.wait(guard).unwrap(); + let vm_clone = vm.clone(); + let jh = std::thread::spawn(move || { + let _guard = l3.0.lock().unwrap(); + vm_clone.DestroyJavaVM(); + l3.2.notify_all(); + }); + assert_eq!(JNI_OK, vm_clone.DetachCurrentThread()); + + let n = JNI_GetCreatedJavaVMs().unwrap(); + assert!(!n.is_empty()); + + let (_guard, tm) = l1.2.wait_timeout(guard, Duration::from_millis(5000)).unwrap(); + assert_eq!(false, tm.timed_out()); + jh.join().unwrap(); + l1.1.notify_all(); + let n = JNI_GetCreatedJavaVMs().unwrap(); + assert!(n.is_empty()); + + //This is a bit of "imagination" but j8 has this behavior. + assert_eq!(JNI_ERR, vm.AttachCurrentThread_str(JNI_VERSION_1_8, None, null_mut()).unwrap_err()); + } + } +} \ No newline at end of file diff --git a/tests/bad_version_launch.rs b/tests/bad_version_launch.rs new file mode 100644 index 0000000..4f25e71 --- /dev/null +++ b/tests/bad_version_launch.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "loadjvm")] +pub mod test { + use jni_simple::*; + + #[test] + fn test() { + unsafe { + load_jvm_from_java_home().expect("failed to load jvm"); + + let args: Vec = vec![]; + + let error_code = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_1-1, &args).unwrap_err(); + assert_eq!(error_code, JNI_EVERSION); + let args: Vec = vec!["-Xmx128M".to_string()]; + let (vm, _env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args).expect("failed to create java VM"); + vm.DestroyJavaVM(); + } + } +} \ No newline at end of file diff --git a/tests/create_bad_argument.rs b/tests/create_bad_argument.rs new file mode 100644 index 0000000..49a6d32 --- /dev/null +++ b/tests/create_bad_argument.rs @@ -0,0 +1,18 @@ +#[cfg(feature = "loadjvm")] +pub mod test { + use jni_simple::*; + #[test] + fn test() { + unsafe { + load_jvm_from_java_home().expect("failed to load jvm"); + + let args: Vec = vec!["-Xmx1SAD".to_string()]; //This option is recognized but intentionally invalid. + + let error_code = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args).unwrap_err(); + assert_eq!(error_code, JNI_EINVAL); + let args: Vec = vec!["-Xmx128M".to_string()]; + let (vm, _env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args).expect("failed to create java VM"); + vm.DestroyJavaVM(); + } + } +} \ No newline at end of file diff --git a/tests/launch_prop.rs b/tests/launch_prop.rs new file mode 100644 index 0000000..f1e3c00 --- /dev/null +++ b/tests/launch_prop.rs @@ -0,0 +1,27 @@ +#[cfg(feature = "loadjvm")] +pub mod test { + use jni_simple::*; + + #[test] + fn test() { + unsafe { + load_jvm_from_java_home().expect("failed to load jvm"); + + let args: Vec = vec!["-Drusttest=12345".to_string()]; + + let (_, env) = JNI_CreateJavaVM_with_string_args(JNI_VERSION_1_8, &args) + .expect("failed to create jvm"); + + let sys = env.FindClass_str("java/lang/System"); + let get_prop = env.GetStaticMethodID_str(sys, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); + + let str = env.NewStringUTF_str("rusttest"); + let obj = env.CallStaticObjectMethodA(sys, get_prop, [str.into()].as_ptr()); + assert!(!obj.is_null()); + let uw = env.GetStringUTFChars_as_string(obj).unwrap().to_lowercase(); + assert_eq!("12345", uw.as_str()); + env.DeleteLocalRef(obj); + env.DeleteLocalRef(str); + } + } +} \ No newline at end of file