From b392821c05e7bd0093651231fb800430d44fd6a0 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Sun, 1 Mar 2020 08:55:27 +0100 Subject: [PATCH] reintroduced field-clearing on Spring test classes, moved to superclass model-intest were indeed very slow, hopefully this helps (again) --- .../test/util/AbstractSpringTest.java | 48 +++++++++++++++++++ ...bstractConfiguredModelIntegrationTest.java | 44 ----------------- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java index 49fe1a4def1..ab0fe6c306e 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java @@ -6,9 +6,13 @@ */ package com.evolveum.midpoint.test.util; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + import org.jetbrains.annotations.NotNull; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.ITestResult; +import org.testng.annotations.AfterClass; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -64,4 +68,48 @@ public String contextName() { public String getTestNameShort() { return TEST_CONTEXT_THREAD_LOCAL.get().getMethod().getMethodName(); } + + /** + * This method null all fields which are not static, final or primitive type. + *

+ * All this is just to make GC work during DirtiesContext after every test class, + * because test class instances are not GCed immediately. + * If they hold autowired fields like sessionFactory (for example + * through SqlRepositoryService impl), their memory footprint is getting big. + *

+ * Note that this does not work for components injected through constructor into + * final fields - if we need this cleanup, make the field non-final. + */ + @AfterClass(alwaysRun = true) + protected void clearClassFields() throws Exception { + logger.trace("Clearing all fields for test class {}", getClass().getName()); + clearClassFields(this, getClass()); + } + + private void clearClassFields(Object object, Class forClass) throws Exception { + if (forClass.getSuperclass() != null) { + clearClassFields(object, forClass.getSuperclass()); + } + + for (Field field : forClass.getDeclaredFields()) { + if (Modifier.isFinal(field.getModifiers()) + || Modifier.isStatic(field.getModifiers()) + || field.getType().isPrimitive()) { + continue; + } + + nullField(object, field); + } + } + + private void nullField(Object obj, Field field) throws Exception { + logger.info("Setting {} to null on {}.", field.getName(), obj.getClass().getSimpleName()); + boolean accessible = field.isAccessible(); +// boolean accessible = field.canAccess(obj); // TODO: after ditching JDK 8 + if (!accessible) { + field.setAccessible(true); + } + field.set(obj, null); + field.setAccessible(accessible); + } } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 7f8d12e1f24..222b2c92c08 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -37,8 +37,6 @@ import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -48,7 +46,6 @@ /** * @author semancik - * */ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegrationTest { @@ -613,47 +610,6 @@ protected PrismObject getDefaultActor() { return userAdministrator; } - // TODO inttest: let's try it without this after 6 years -// @AfterClass(alwaysRun = true) - public void clearClassFields() throws Exception { - logger.trace("Clearing all fields for test class {}", getClass().getName()); - nullAllFields(this, getClass()); - } - - /** - * This method null all fields which are not static, final or primitive type. - * - * All this is just to make GC work during DirtiesContext after every test class, - * because memory consumption is too big. Test class instances can't be GCed - * immediately. If they holds autowired fields like sessionFactory (for example - * through SqlRepositoryService impl), their memory footprint is getting big. - */ - public void nullAllFields(Object object, Class forClass) throws Exception { - if (forClass.getSuperclass() != null) { - nullAllFields(object, forClass.getSuperclass()); - } - - for (Field field : forClass.getDeclaredFields()) { - if (Modifier.isFinal(field.getModifiers()) - || Modifier.isStatic(field.getModifiers()) - || field.getType().isPrimitive()) { - continue; - } - - nullField(object, field); - } - } - - private void nullField(Object obj, Field field) throws Exception { - logger.info("Setting {} to null on {}.", new Object[]{field.getName(), obj.getClass().getSimpleName()}); - boolean accessible = field.isAccessible(); - if (!accessible) { - field.setAccessible(true); - } - field.set(obj, null); - field.setAccessible(accessible); - } - protected PrismSchema getPiracySchema() { return prismContext.getSchemaRegistry().findSchemaByNamespace(NS_PIRACY); }