#10226 disable leak tracking only for client/server or impacted transports

Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
Ludovic Orban 2023-08-25 12:42:17 +02:00
parent 18797fad57
commit a4e33a019f
7 changed files with 78 additions and 80 deletions

View File

@ -13,14 +13,7 @@
package org.eclipse.jetty.fcgi.server;
import java.lang.management.ManagementFactory;
import java.lang.reflect.AnnotatedElement;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import javax.management.MBeanServer;
import org.awaitility.Awaitility;
import org.eclipse.jetty.client.HttpClient;
@ -38,9 +31,6 @@ import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Tags;
import org.junit.jupiter.api.TestInfo;
import static org.junit.jupiter.api.Assertions.fail;
@ -80,13 +70,10 @@ public abstract class AbstractHttpClientServerTest
}
@AfterEach
public void dispose(TestInfo testInfo) throws Exception
public void dispose()
{
try
{
if (isLeakTrackingDisabled(testInfo))
return;
if (serverBufferPool != null)
{
try
@ -95,8 +82,6 @@ public abstract class AbstractHttpClientServerTest
}
catch (Exception e)
{
String className = testInfo.getTestClass().orElseThrow().getName();
dumpHeap("server-" + className);
fail(e.getMessage() + "\n---\nServer Leaks: " + serverBufferPool.dumpLeaks() + "---\n");
}
}
@ -108,8 +93,6 @@ public abstract class AbstractHttpClientServerTest
}
catch (Exception e)
{
String className = testInfo.getTestClass().orElseThrow().getName();
dumpHeap("client-" + className);
fail(e.getMessage() + "\n---\nClient Leaks: " + clientBufferPool.dumpLeaks() + "---\n");
}
}
@ -120,52 +103,4 @@ public abstract class AbstractHttpClientServerTest
LifeCycle.stop(server);
}
}
private static boolean isLeakTrackingDisabled(TestInfo testInfo)
{
String disableLeakTrackingTagValue = "DisableLeakTracking";
return isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue) ||
isAnnotatedWithTagValue(testInfo.getTestClass().orElseThrow(), disableLeakTrackingTagValue);
}
private static boolean isAnnotatedWithTagValue(AnnotatedElement annotatedElement, String tagValue)
{
Tags tags = annotatedElement.getAnnotation(Tags.class);
if (tags != null)
{
for (Tag tag : tags.value())
{
if (tag != null && tagValue.equalsIgnoreCase(tag.value()))
return true;
}
return false;
}
else
{
Tag tag = annotatedElement.getAnnotation(Tag.class);
return tag != null && tagValue.equalsIgnoreCase(tag.value());
}
}
private static void dumpHeap(String testMethodName) throws Exception
{
Path targetDir = Path.of("target/leaks");
if (Files.exists(targetDir))
{
try (Stream<Path> stream = Files.walk(targetDir))
{
stream.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(java.io.File::delete);
}
}
Files.createDirectories(targetDir);
String dumpName = targetDir.resolve(testMethodName + ".hprof").toString();
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
Class<?> mxBeanClass = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
Object mxBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", mxBeanClass);
mxBeanClass.getMethod("dumpHeap", String.class, boolean.class).invoke(mxBean, dumpName, true);
}
}

View File

@ -125,10 +125,7 @@ public class AbstractTest
{
try
{
if (isLeakTrackingDisabled(testInfo))
return;
if (serverBufferPool != null)
if (serverBufferPool != null && !isLeakTrackingDisabled(testInfo, "server"))
{
try
{
@ -141,7 +138,7 @@ public class AbstractTest
fail(e.getMessage() + "\n---\nServer Leaks: " + serverBufferPool.dumpLeaks() + "---\n");
}
}
if (clientBufferPool != null)
if (clientBufferPool != null && !isLeakTrackingDisabled(testInfo, "client"))
{
try
{
@ -162,11 +159,52 @@ public class AbstractTest
}
}
private static boolean isLeakTrackingDisabled(TestInfo testInfo)
private static boolean isLeakTrackingDisabled(TestInfo testInfo, String tagSubValue)
{
String disableLeakTrackingTagValue = "DisableLeakTracking";
return isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue) ||
String[] split = testInfo.getDisplayName().replace(",", " ").split(" ");
String transports = split.length > 1 ? split[1] : "";
String[] transportNames = transports.split("\\|");
boolean disabled = isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue) ||
isAnnotatedWithTagValue(testInfo.getTestClass().orElseThrow(), disableLeakTrackingTagValue);
if (disabled)
{
System.err.println("Not tracking leaks");
return true;
}
for (String transportName : transportNames)
{
disabled = isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue + ":" + transportName) ||
isAnnotatedWithTagValue(testInfo.getTestClass().orElseThrow(), disableLeakTrackingTagValue + ":" + transportName);
if (disabled)
{
System.err.println("Not tracking leaks for transport " + transportName);
return true;
}
}
disabled = isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue + ":" + tagSubValue) ||
isAnnotatedWithTagValue(testInfo.getTestClass().orElseThrow(), disableLeakTrackingTagValue + ":" + tagSubValue);
if (disabled)
{
System.err.println("Not tracking leaks for " + tagSubValue);
return true;
}
for (String transportName : transportNames)
{
disabled = isAnnotatedWithTagValue(testInfo.getTestMethod().orElseThrow(), disableLeakTrackingTagValue + ":" + tagSubValue + ":" + transportName) ||
isAnnotatedWithTagValue(testInfo.getTestClass().orElseThrow(), disableLeakTrackingTagValue + ":" + tagSubValue + ":" + transportName);
if (disabled)
{
System.err.println("Not tracking leaks for " + tagSubValue + " using transport " + transportName);
return true;
}
}
return disabled;
}
private static boolean isAnnotatedWithTagValue(AnnotatedElement annotatedElement, String tagValue)

View File

@ -35,7 +35,7 @@ public class HttpClientIdleTimeoutTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:server:FCGI")
public void testClientIdleTimeout(Transport transport) throws Exception
{
start(transport, new Handler.Abstract()
@ -71,7 +71,7 @@ public class HttpClientIdleTimeoutTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:server:FCGI")
public void testRequestIdleTimeout(Transport transport) throws Exception
{
start(transport, new Handler.Abstract()

View File

@ -78,7 +78,6 @@ import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Tag("DisableLeakTracking")
public class HttpClientStreamTest extends AbstractTest
{
@ParameterizedTest
@ -215,6 +214,8 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:H2")
@Tag("DisableLeakTracking:client:H2C")
public void testDownloadWithFailure(Transport transport) throws Exception
{
byte[] data = new byte[64 * 1024];
@ -266,6 +267,7 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:FCGI")
public void testInputStreamResponseListenerClosedBeforeReading(Transport transport) throws Exception
{
start(transport, new Handler.Abstract()
@ -294,6 +296,9 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:HTTP")
@Tag("DisableLeakTracking:client:FCGI")
@Tag("DisableLeakTracking:client:UNIX_DOMAIN")
public void testInputStreamResponseListenerClosedBeforeContent(Transport transport) throws Exception
{
AtomicReference<HandlerContext> contextRef = new AtomicReference<>();
@ -337,6 +342,9 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:H2C")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:client:FCGI")
public void testInputStreamResponseListenerClosedWhileWaiting(Transport transport) throws Exception
{
byte[] chunk1 = new byte[]{0, 1};
@ -389,6 +397,7 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:FCGI")
public void testInputStreamResponseListenerFailedWhileWaiting(Transport transport) throws Exception
{
start(transport, new Handler.Abstract()
@ -491,6 +500,8 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:client:FCGI")
@Tag("flaky")
public void testDownloadWithCloseBeforeContent(Transport transport) throws Exception
{
@ -538,6 +549,9 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@Tag("flaky")
@Tag("DisableLeakTracking:client:HTTP")
@Tag("DisableLeakTracking:client:FCGI")
@Tag("DisableLeakTracking:client:UNIX_DOMAIN")
@MethodSource("transports")
public void testDownloadWithCloseMiddleOfContent(Transport transport) throws Exception
{
@ -962,6 +976,11 @@ public class HttpClientStreamTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:server:HTTP")
@Tag("DisableLeakTracking:server:HTTPS")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:server:FCGI")
@Tag("DisableLeakTracking:server:UNIX_DOMAIN")
public void testUploadWithConcurrentServerCloseClosesStream(Transport transport) throws Exception
{
CountDownLatch serverLatch = new CountDownLatch(1);

View File

@ -290,7 +290,8 @@ public class HttpClientTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:client:FCGI")
public void testRequestAfterFailedRequest(Transport transport) throws Exception
{
int length = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
@ -837,7 +838,8 @@ public class HttpClientTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:client:FCGI")
public void testContentSourceListenersFailure(Transport transport) throws Exception
{
int totalBytes = 1024;
@ -994,7 +996,8 @@ public class HttpClientTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:client:H3")
@Tag("DisableLeakTracking:client:FCGI")
public void testParallelContentSourceListenersTotalFailure(Transport transport) throws Exception
{
start(transport, new TestHandler(1024));

View File

@ -386,6 +386,7 @@ public class HttpClientTimeoutTest extends AbstractTest
@ParameterizedTest
@MethodSource("transports")
@Tag("DisableLeakTracking:client:FCGI")
public void testVeryShortTimeout(Transport transport) throws Exception
{
start(transport, new EmptyServerHandler());

View File

@ -95,7 +95,9 @@ public class ServerTimeoutsTest extends AbstractTest
@ParameterizedTest
@MethodSource("transportsAndTrueIdleTimeoutListeners")
@Tag("DisableLeakTracking")
@Tag("DisableLeakTracking:server:HTTP")
@Tag("DisableLeakTracking:server:HTTPS")
@Tag("DisableLeakTracking:server:UNIX_DOMAIN")
public void testIdleTimeoutWithDemand(Transport transport, boolean listener) throws Exception
{
AtomicBoolean listenerCalled = new AtomicBoolean();