Compress the heap dump generated by TestUtils.dump()

Motivation:

It takes too long to download the heap dump from the CI server.

Modifications:

Compress the heap dump as much as possible.

Result:

When heap dump is generated by certain test failure, the generated heap
dump file is about 3 times smaller than before, although the compression
time will increase the build time when the test fails.
This commit is contained in:
Trustin Lee 2014-12-14 11:59:09 +09:00
parent 0bc0851569
commit cbbf5eb96b
3 changed files with 67 additions and 24 deletions

View File

@ -710,6 +710,14 @@
<version>1.8.1</version> <version>1.8.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Test dependency for generating a compressed heap dump file -->
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.5</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

View File

@ -29,26 +29,6 @@
<name>Netty/Testsuite</name> <name>Netty/Testsuite</name>
<dependencies> <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-junit4</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>netty-transport-sctp</artifactId> <artifactId>netty-transport-sctp</artifactId>
@ -75,6 +55,12 @@
<classifier>${os.detected.classifier}</classifier> <classifier>${os.detected.classifier}</classifier>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<properties> <properties>

View File

@ -20,11 +20,15 @@ import io.netty.util.NetUtil;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import org.junit.rules.TestName; import org.junit.rules.TestName;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.XZOutputStream;
import javax.management.MBeanServer; import javax.management.MBeanServer;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo; import java.lang.management.ThreadInfo;
@ -238,6 +242,51 @@ public final class TestUtils {
hotspotMXBeanDumpHeap.invoke(hotspotMXBean, filename, true); hotspotMXBeanDumpHeap.invoke(hotspotMXBean, filename, true);
} catch (Exception e) { } catch (Exception e) {
logger.warn("Failed to dump heap: {}", filename, 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);
} }
} }