Compress the heap dump after tests are finished
Motivation: Tests sometimes time out because it took too long to compress the generated heap dump. Modifications: - Move the compression logic to a new method 'compressHeapDumps()' - Call TestUtils.compressHeapDumps() at the end of the tests, so that the tests do not fail because of timeout Result: JUnit reports the real cause of the test failure instead of timeout exception.
This commit is contained in:
parent
9ee75126eb
commit
c7b407e288
@ -26,7 +26,10 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.testsuite.util.TestUtils;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Random;
|
||||
@ -36,6 +39,9 @@ import static org.junit.Assert.*;
|
||||
|
||||
public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
|
||||
@Rule
|
||||
public final Timeout globalTimeout = new Timeout(60000);
|
||||
|
||||
private static final Random random = new Random();
|
||||
static final byte[] data = new byte[1048576];
|
||||
|
||||
@ -43,7 +49,12 @@ public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
random.nextBytes(data);
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
@AfterClass
|
||||
public static void compressHeapDumps() throws Exception {
|
||||
TestUtils.compressHeapDumps();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatheringWrite() throws Throwable {
|
||||
run();
|
||||
}
|
||||
@ -52,7 +63,7 @@ public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
testGatheringWrite0(sb, cb, data, false, true);
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
@Test
|
||||
public void testGatheringWriteNotAutoRead() throws Throwable {
|
||||
run();
|
||||
}
|
||||
@ -61,7 +72,7 @@ public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
testGatheringWrite0(sb, cb, data, false, false);
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
@Test
|
||||
public void testGatheringWriteWithComposite() throws Throwable {
|
||||
run();
|
||||
}
|
||||
@ -70,7 +81,7 @@ public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
testGatheringWrite0(sb, cb, data, true, false);
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
@Test
|
||||
public void testGatheringWriteWithCompositeNotAutoRead() throws Throwable {
|
||||
run();
|
||||
}
|
||||
@ -80,7 +91,7 @@ public class SocketGatheringWriteTest extends AbstractSocketTest {
|
||||
}
|
||||
|
||||
// Test for https://github.com/netty/netty/issues/2647
|
||||
@Test(timeout = 60000)
|
||||
@Test
|
||||
public void testGatheringWriteBig() throws Throwable {
|
||||
run();
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@ -189,6 +190,11 @@ public class SocketSslEchoTest extends AbstractSocketTest {
|
||||
run();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void compressHeapDumps() throws Exception {
|
||||
TestUtils.compressHeapDumps();
|
||||
}
|
||||
|
||||
public void testSslEcho(ServerBootstrap sb, Bootstrap cb) throws Throwable {
|
||||
final ExecutorService delegatedTaskExecutor = Executors.newCachedThreadPool();
|
||||
final EchoHandler sh = new EchoHandler(true);
|
||||
|
@ -27,6 +27,7 @@ import javax.management.MBeanServer;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@ -44,6 +45,7 @@ import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class TestUtils {
|
||||
|
||||
@ -59,6 +61,8 @@ public final class TestUtils {
|
||||
private static final Method hotspotMXBeanDumpHeap;
|
||||
private static final Object hotspotMXBean;
|
||||
|
||||
private static final long DUMP_PROGRESS_LOGGING_INTERVAL = TimeUnit.SECONDS.toNanos(5);
|
||||
|
||||
static {
|
||||
// Populate the list of random ports.
|
||||
for (int i = START_PORT; i < END_PORT; i ++) {
|
||||
@ -226,6 +230,79 @@ public final class TestUtils {
|
||||
dumpThreads(threadDumpFile);
|
||||
}
|
||||
|
||||
public static void compressHeapDumps() throws IOException {
|
||||
final File[] files = new File(System.getProperty("user.dir")).listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".hprof");
|
||||
}
|
||||
});
|
||||
|
||||
final byte[] buf = new byte[65536];
|
||||
final LZMA2Options options = new LZMA2Options(9);
|
||||
|
||||
for (File file: files) {
|
||||
final String filename = file.toString();
|
||||
final String xzFilename = filename + ".xz";
|
||||
final long fileLength = file.length();
|
||||
|
||||
logger.info("Compressing the heap dump: {}", xzFilename);
|
||||
|
||||
long lastLogTime = System.nanoTime();
|
||||
long counter = 0;
|
||||
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = new FileInputStream(filename);
|
||||
out = new XZOutputStream(new FileOutputStream(xzFilename), options);
|
||||
for (;;) {
|
||||
int readBytes = in.read(buf);
|
||||
if (readBytes < 0) {
|
||||
break;
|
||||
}
|
||||
if (readBytes == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
out.write(buf, 0, readBytes);
|
||||
counter += readBytes;
|
||||
|
||||
long currentTime = System.nanoTime();
|
||||
if (currentTime - lastLogTime > DUMP_PROGRESS_LOGGING_INTERVAL) {
|
||||
logger.info("Compressing the heap dump: {} ({}%)",
|
||||
xzFilename, counter * 100 / fileLength);
|
||||
lastLogTime = currentTime;
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to compress the heap dump: {}", xzFilename, e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignored) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the uncompressed dump in favor of the compressed one.
|
||||
if (!file.delete()) {
|
||||
logger.warn("Failed to delete the uncompressed heap dump: {}", filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String timestamp() {
|
||||
return new SimpleDateFormat("HHmmss.SSS").format(new Date());
|
||||
}
|
||||
@ -242,51 +319,6 @@ public final class TestUtils {
|
||||
hotspotMXBeanDumpHeap.invoke(hotspotMXBean, filename, true);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to dump heap: {}", filename, e);
|
||||
return;
|
||||
}
|
||||
|
||||
final String xzFilename = filename + ".xz";
|
||||
logger.info("Compressing the heap dump: {}", xzFilename);
|
||||
final byte[] buf = new byte[65536];
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
in = new FileInputStream(filename);
|
||||
out = new XZOutputStream(new FileOutputStream(xzFilename), new LZMA2Options(9));
|
||||
for (;;) {
|
||||
int readBytes = in.read(buf);
|
||||
if (readBytes < 0) {
|
||||
break;
|
||||
}
|
||||
if (readBytes == 0) {
|
||||
continue;
|
||||
}
|
||||
out.write(buf, 0, readBytes);
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to compress the heap dump: {}", xzFilename, e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignored) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException ignored) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the uncompressed dump in favor of the compressed one.
|
||||
if (!file.delete()) {
|
||||
logger.warn("Failed to delete the uncompressed heap dump: {}", filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user