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:
parent
0bc0851569
commit
cbbf5eb96b
8
pom.xml
8
pom.xml
@ -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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user