From fd31db920a27e242cd550099d3c128ea7bdfd935 Mon Sep 17 00:00:00 2001 From: amirdeljouyi Date: Wed, 1 Jul 2026 22:54:06 +0200 Subject: [PATCH 1/2] test: cover implementation bridge accessor initialization --- .../ImplementationBridgeHelpersTest.java | 124 ++++++++++++++++-- 1 file changed, 114 insertions(+), 10 deletions(-) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java index 24a448c54b84..b414911517da 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java @@ -14,6 +14,9 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CyclicBarrier; @@ -30,18 +33,16 @@ public class ImplementationBridgeHelpersTest { private static final Logger logger = LoggerFactory.getLogger(ImplementationBridgeHelpers.class); + private static final String HELPER_CLASS_SUFFIX = "Helper"; + private static final Class[] DECLARED_CLASSES = ImplementationBridgeHelpers.class.getDeclaredClasses(); @Test(groups = { "unit" }) public void accessorInitialization() { - String helperClassSuffix = "Helper"; - - Class[] declaredClasses = ImplementationBridgeHelpers.class.getDeclaredClasses(); - try { - for (Class declaredClass : declaredClasses) { + for (Class declaredClass : DECLARED_CLASSES) { - if (declaredClass.getSimpleName().endsWith(helperClassSuffix)) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { Field[] fields = declaredClass.getDeclaredFields(); boolean isAccessorReset = false; @@ -72,11 +73,9 @@ public void accessorInitialization() { ModelBridgeInternal.initializeAllAccessors(); UtilBridgeInternal.initializeAllAccessors(); - declaredClasses = ImplementationBridgeHelpers.class.getDeclaredClasses(); - - for (Class declaredClass : declaredClasses) { + for (Class declaredClass : DECLARED_CLASSES) { - if (declaredClass.getSimpleName().endsWith(helperClassSuffix)) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { logger.info("Helper class name : {}", declaredClass.getSimpleName()); @@ -707,4 +706,109 @@ public void noStaticOrInstanceAccessorFieldsInConsumingClasses() throws Exceptio + "Violations:\n" + String.join("\n", violations)) .isEmpty(); } + + @Test(groups = { "unit" }) + public void accessorInitializationFromAccessorGetter() throws ReflectiveOperationException { + int accessorGetterCount = 0; + + for (Class declaredClass : DECLARED_CLASSES) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { + boolean helperAccessorGetterInvoked = false; + + for (Method method : declaredClass.getDeclaredMethods()) { + if (isAccessorGetter(method)) { + resetAccessorReferences(); + assertThat(method.invoke(null)).isNotNull(); + + helperAccessorGetterInvoked = true; + accessorGetterCount++; + } + } + + assertThat(helperAccessorGetterInvoked).isTrue(); + } + } + + assertThat(accessorGetterCount).isGreaterThan(0); + } + + @Test(groups = { "unit" }) + public void accessorSettersKeepExistingAccessor() throws ReflectiveOperationException { + int accessorSetterCount = 0; + + for (Class declaredClass : DECLARED_CLASSES) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { + boolean helperAccessorSetterInvoked = false; + + for (Method method : declaredClass.getDeclaredMethods()) { + if (isAccessorSetter(method)) { + Method getter = findAccessorGetter(declaredClass, method.getParameterTypes()[0]); + Object firstAccessor = proxyAccessor(method.getParameterTypes()[0]); + Object secondAccessor = proxyAccessor(method.getParameterTypes()[0]); + + resetAccessorReferences(); + method.invoke(null, firstAccessor); + method.invoke(null, secondAccessor); + + assertThat(getter.invoke(null)).isSameAs(firstAccessor); + helperAccessorSetterInvoked = true; + accessorSetterCount++; + } + } + + assertThat(helperAccessorSetterInvoked).isTrue(); + } + } + + assertThat(accessorSetterCount).isGreaterThan(0); + } + + private static boolean isAccessorGetter(Method method) { + return Modifier.isStatic(method.getModifiers()) + && method.getParameterCount() == 0 + && method.getName().startsWith("get") + && method.getReturnType().getSimpleName().endsWith("Accessor"); + } + + private static boolean isAccessorSetter(Method method) { + return Modifier.isStatic(method.getModifiers()) + && method.getParameterCount() == 1 + && method.getName().startsWith("set") + && method.getParameterTypes()[0].getSimpleName().endsWith("Accessor"); + } + + private static Method findAccessorGetter(Class declaredClass, Class accessorType) { + for (Method method : declaredClass.getDeclaredMethods()) { + if (isAccessorGetter(method) && method.getReturnType().equals(accessorType)) { + return method; + } + } + + throw new AssertionError("No accessor getter found for " + accessorType.getName()); + } + + private static Object proxyAccessor(Class accessorType) { + return Proxy.newProxyInstance( + accessorType.getClassLoader(), + new Class[] { accessorType }, + (proxy, method, args) -> null); + } + + private static void resetAccessorReferences() throws IllegalAccessException { + for (Class declaredClass : DECLARED_CLASSES) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { + for (Field field : declaredClass.getDeclaredFields()) { + if (field.getName().contains("accessor")) { + field.setAccessible(true); + ((AtomicReference) FieldUtils.readStaticField(field)).set(null); + } + + if (field.getName().contains("ClassLoaded")) { + field.setAccessible(true); + ((AtomicBoolean) FieldUtils.readStaticField(field)).set(false); + } + } + } + } + } } From adaf45623fb55b10671cdb678fc2ca8a8cfbebd6 Mon Sep 17 00:00:00 2001 From: amirdeljouyi Date: Tue, 7 Jul 2026 13:49:45 +0200 Subject: [PATCH 2/2] test: restore implementation bridge accessors --- .../ImplementationBridgeHelpersTest.java | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java index b414911517da..0a5c136f9479 100644 --- a/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java +++ b/sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/ImplementationBridgeHelpersTest.java @@ -736,28 +736,32 @@ public void accessorInitializationFromAccessorGetter() throws ReflectiveOperatio public void accessorSettersKeepExistingAccessor() throws ReflectiveOperationException { int accessorSetterCount = 0; - for (Class declaredClass : DECLARED_CLASSES) { - if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { - boolean helperAccessorSetterInvoked = false; + try { + for (Class declaredClass : DECLARED_CLASSES) { + if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) { + boolean helperAccessorSetterInvoked = false; - for (Method method : declaredClass.getDeclaredMethods()) { - if (isAccessorSetter(method)) { - Method getter = findAccessorGetter(declaredClass, method.getParameterTypes()[0]); - Object firstAccessor = proxyAccessor(method.getParameterTypes()[0]); - Object secondAccessor = proxyAccessor(method.getParameterTypes()[0]); + for (Method method : declaredClass.getDeclaredMethods()) { + if (isAccessorSetter(method)) { + Method getter = findAccessorGetter(declaredClass, method.getParameterTypes()[0]); + Object firstAccessor = proxyAccessor(method.getParameterTypes()[0]); + Object secondAccessor = proxyAccessor(method.getParameterTypes()[0]); - resetAccessorReferences(); - method.invoke(null, firstAccessor); - method.invoke(null, secondAccessor); + resetAccessorReferences(); + method.invoke(null, firstAccessor); + method.invoke(null, secondAccessor); - assertThat(getter.invoke(null)).isSameAs(firstAccessor); - helperAccessorSetterInvoked = true; - accessorSetterCount++; + assertThat(getter.invoke(null)).isSameAs(firstAccessor); + helperAccessorSetterInvoked = true; + accessorSetterCount++; + } } - } - assertThat(helperAccessorSetterInvoked).isTrue(); + assertThat(helperAccessorSetterInvoked).isTrue(); + } } + } finally { + restoreAccessorReferences(); } assertThat(accessorSetterCount).isGreaterThan(0); @@ -794,6 +798,11 @@ private static Object proxyAccessor(Class accessorType) { (proxy, method, args) -> null); } + private static void restoreAccessorReferences() throws IllegalAccessException { + resetAccessorReferences(); + ImplementationBridgeHelpers.initializeAllAccessors(); + } + private static void resetAccessorReferences() throws IllegalAccessException { for (Class declaredClass : DECLARED_CLASSES) { if (declaredClass.getSimpleName().endsWith(HELPER_CLASS_SUFFIX)) {