@@ -37,8 +37,87 @@ class JvmSupportGlobalSetup {
3737};
3838static JvmSupportGlobalSetup jvm_support_global_setup;
3939
40- TEST (JvmSupportThreadClassificationTest, NullInputsFailClosed) {
41- EXPECT_FALSE (JVMSupport::isPlatformThread (nullptr , nullptr ));
40+ class JvmSupportThreadClassificationTest : public ::testing::Test {
41+ protected:
42+ using JniFunction = void (JNICALL *)();
43+
44+ static constexpr int GET_VERSION_INDEX = 4 ;
45+ static constexpr int IS_VIRTUAL_THREAD_INDEX = 234 ;
46+ static constexpr int FUNCTION_TABLE_SIZE = IS_VIRTUAL_THREAD_INDEX + 1 ;
47+
48+ inline static jint jni_version;
49+ inline static jboolean virtual_thread;
50+ inline static int is_virtual_thread_calls;
51+ inline static jobject last_thread;
52+
53+ JniFunction function_table[FUNCTION_TABLE_SIZE ]{};
54+ JNIEnv jni{};
55+ _jobject thread_object;
56+ jthread thread = &thread_object;
57+
58+ static jint JNICALL getVersion (JNIEnv*) {
59+ return jni_version;
60+ }
61+
62+ static jboolean JNICALL isVirtualThread (JNIEnv*, jobject candidate) {
63+ is_virtual_thread_calls++;
64+ last_thread = candidate;
65+ return virtual_thread;
66+ }
67+
68+ void SetUp () override {
69+ jni_version = 0x00150000 ;
70+ virtual_thread = JNI_FALSE ;
71+ is_virtual_thread_calls = 0 ;
72+ last_thread = nullptr ;
73+
74+ function_table[GET_VERSION_INDEX ] = reinterpret_cast <JniFunction>(&getVersion);
75+ function_table[IS_VIRTUAL_THREAD_INDEX ] = reinterpret_cast <JniFunction>(&isVirtualThread);
76+ jni.functions = reinterpret_cast <const JNINativeInterface_*>(function_table);
77+ }
78+ };
79+
80+ TEST_F (JvmSupportThreadClassificationTest, NullInputsFailClosed) {
81+ EXPECT_FALSE (JVMSupport::isPlatformThread (nullptr , thread));
82+ EXPECT_FALSE (JVMSupport::isPlatformThread (&jni, nullptr ));
83+ }
84+
85+ TEST_F (JvmSupportThreadClassificationTest, InvalidJniVersionFailsClosed) {
86+ jni_version = 0 ;
87+
88+ EXPECT_FALSE (JVMSupport::isPlatformThread (&jni, thread));
89+ EXPECT_EQ (0 , is_virtual_thread_calls);
90+ }
91+
92+ TEST_F (JvmSupportThreadClassificationTest, PreJni21ThreadIsPlatform) {
93+ jni_version = 0x000a0000 ;
94+ function_table[IS_VIRTUAL_THREAD_INDEX ] = nullptr ;
95+
96+ EXPECT_TRUE (JVMSupport::isPlatformThread (&jni, thread));
97+ EXPECT_EQ (0 , is_virtual_thread_calls);
98+ }
99+
100+ TEST_F (JvmSupportThreadClassificationTest, Jni21PlatformThreadIsAccepted) {
101+ virtual_thread = JNI_FALSE ;
102+
103+ EXPECT_TRUE (JVMSupport::isPlatformThread (&jni, thread));
104+ EXPECT_EQ (1 , is_virtual_thread_calls);
105+ EXPECT_EQ (thread, last_thread);
106+ }
107+
108+ TEST_F (JvmSupportThreadClassificationTest, Jni21VirtualThreadIsRejected) {
109+ virtual_thread = JNI_TRUE ;
110+
111+ EXPECT_FALSE (JVMSupport::isPlatformThread (&jni, thread));
112+ EXPECT_EQ (1 , is_virtual_thread_calls);
113+ EXPECT_EQ (thread, last_thread);
114+ }
115+
116+ TEST_F (JvmSupportThreadClassificationTest, MissingJni21FunctionFailsClosed) {
117+ function_table[IS_VIRTUAL_THREAD_INDEX ] = nullptr ;
118+
119+ EXPECT_FALSE (JVMSupport::isPlatformThread (&jni, thread));
120+ EXPECT_EQ (0 , is_virtual_thread_calls);
42121}
43122
44123// ---------------------------------------------------------------------------
0 commit comments