This is an automated email from the ASF dual-hosted git repository. ericpai pushed a commit to branch improve/iotdb-3558 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 66369781c5cf3b7b804521ebb334cb43b576c3d3 Author: ericpai <[email protected]> AuthorDate: Wed Jun 22 16:32:00 2022 +0800 [IOTDB-3558] Dump node stacks if IT test request timeout --- .../java/org/apache/iotdb/it/env/AbstractEnv.java | 62 ++++----- .../apache/iotdb/it/env/AbstractNodeWrapper.java | 149 +++++++++++++++++++-- .../org/apache/iotdb/it/env/ConfigNodeWrapper.java | 44 +++--- .../org/apache/iotdb/it/env/DataNodeWrapper.java | 33 ++--- .../org/apache/iotdb/it/env/IoTDBTestRunner.java | 2 +- .../org/apache/iotdb/it/env/RemoteServerEnv.java | 7 +- .../iotdb/it/env/StandaloneDataNodeWrapper.java | 5 +- .../apache/iotdb/it/env/StandaloneOnMppEnv.java | 16 +-- .../java/org/apache/iotdb/itbase/env/BaseEnv.java | 4 +- .../apache/iotdb/itbase/env/BaseNodeWrapper.java | 4 + .../itbase/runtime/ParallelRequestDelegate.java | 3 + .../org/apache/iotdb/db/it/env/StandaloneEnv.java | 6 +- 12 files changed, 224 insertions(+), 111 deletions(-) diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractEnv.java index c41ea0c432..27545e8dc7 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractEnv.java @@ -34,9 +34,7 @@ import org.slf4j.LoggerFactory; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; @@ -53,28 +51,28 @@ public abstract class AbstractEnv implements BaseEnv { protected List<ConfigNodeWrapper> configNodeWrapperList; protected List<DataNodeWrapper> dataNodeWrapperList; private final Random rand = new Random(); - protected String nextTestCase = null; + protected String testMethodName = null; - protected void initEnvironment(int configNodesNum, int dataNodesNum) throws InterruptedException { + protected void initEnvironment(int configNodesNum, int dataNodesNum) { this.configNodeWrapperList = new ArrayList<>(); this.dataNodeWrapperList = new ArrayList<>(); - final String testName = getTestClassName() + getNextTestCaseString(); + final String testClassName = getTestClassName(); + final String testMethodName = getTestMethodName(); - ConfigNodeWrapper seedConfigNodeWrapper = new ConfigNodeWrapper(true, "", testName); + ConfigNodeWrapper seedConfigNodeWrapper = + new ConfigNodeWrapper(true, "", testClassName, testMethodName); seedConfigNodeWrapper.createDir(); seedConfigNodeWrapper.changeConfig(ConfigFactory.getConfig().getConfignodeProperties()); seedConfigNodeWrapper.start(); String targetConfigNode = seedConfigNodeWrapper.getIpAndPortString(); this.configNodeWrapperList.add(seedConfigNodeWrapper); - logger.info( - "In test " + testName + " SeedConfigNode " + seedConfigNodeWrapper.getId() + " started."); List<String> configNodeEndpoints = new ArrayList<>(); RequestDelegate<Void> configNodesDelegate = new SerialRequestDelegate<>(configNodeEndpoints); for (int i = 1; i < configNodesNum; i++) { ConfigNodeWrapper configNodeWrapper = - new ConfigNodeWrapper(false, targetConfigNode, testName); + new ConfigNodeWrapper(false, targetConfigNode, testClassName, testMethodName); this.configNodeWrapperList.add(configNodeWrapper); configNodeEndpoints.add(configNodeWrapper.getIpAndPortString()); configNodeWrapper.createDir(); @@ -82,8 +80,6 @@ public abstract class AbstractEnv implements BaseEnv { configNodesDelegate.addRequest( () -> { configNodeWrapper.start(); - logger.info( - "In test " + testName + " ConfigNode " + configNodeWrapper.getId() + " started."); return null; }); } @@ -98,7 +94,8 @@ public abstract class AbstractEnv implements BaseEnv { RequestDelegate<Void> dataNodesDelegate = new ParallelRequestDelegate<>(dataNodeEndpoints, NODE_START_TIMEOUT); for (int i = 0; i < dataNodesNum; i++) { - DataNodeWrapper dataNodeWrapper = new DataNodeWrapper(targetConfigNode, testName); + DataNodeWrapper dataNodeWrapper = + new DataNodeWrapper(targetConfigNode, testClassName, testMethodName); this.dataNodeWrapperList.add(dataNodeWrapper); dataNodeEndpoints.add(dataNodeWrapper.getIpAndPortString()); dataNodeWrapper.createDir(); @@ -106,8 +103,6 @@ public abstract class AbstractEnv implements BaseEnv { dataNodesDelegate.addRequest( () -> { dataNodeWrapper.start(); - logger.info( - "In test " + testName + " DataNode " + dataNodeWrapper.getId() + " started."); return null; }); } @@ -133,7 +128,7 @@ public abstract class AbstractEnv implements BaseEnv { configNodeWrapper.waitingToShutDown(); configNodeWrapper.destroyDir(); } - nextTestCase = null; + testMethodName = null; } public String getTestClassName() { @@ -147,19 +142,6 @@ public abstract class AbstractEnv implements BaseEnv { return "UNKNOWN-IT"; } - public String getTestClassNameAndDate() { - Date date = new Date(); - SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmmss"); - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - for (StackTraceElement stackTraceElement : stack) { - String className = stackTraceElement.getClassName(); - if (className.endsWith("IT")) { - return className.substring(className.lastIndexOf(".") + 1) + "-" + formatter.format(date); - } - } - return "IT"; - } - public void testWorking() { List<String> endpoints = dataNodeWrapperList.stream() @@ -205,11 +187,6 @@ public abstract class AbstractEnv implements BaseEnv { return new ClusterTestConnection(getWriteConnection(null), getReadConnections(null)); } - @Override - public void setNextTestCaseName(String testCaseName) { - nextTestCase = testCaseName; - } - private Connection getConnection(String endpoint, int queryTimeout) throws SQLException { IoTDBConnection connection = (IoTDBConnection) @@ -287,10 +264,21 @@ public abstract class AbstractEnv implements BaseEnv { return sb.toString(); } - public String getNextTestCaseString() { - if (nextTestCase != null) { - return "_" + nextTestCase; + public String getTestMethodName() { + return testMethodName; + } + + @Override + public void setTestMethodName(String testMethodName) { + this.testMethodName = testMethodName; + } + + public void dumpTestJVMSnapshot() { + for (ConfigNodeWrapper configNodeWrapper : configNodeWrapperList) { + configNodeWrapper.dumpJVMSnapshot(testMethodName); + } + for (DataNodeWrapper dataNodeWrapper : dataNodeWrapperList) { + dataNodeWrapper.dumpJVMSnapshot(testMethodName); } - return ""; } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractNodeWrapper.java index c2390690b0..dcaf56fdc0 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/AbstractNodeWrapper.java @@ -25,15 +25,32 @@ import org.apache.commons.lang3.SystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -47,16 +64,20 @@ public abstract class AbstractNodeWrapper implements BaseNodeWrapper { System.getProperty("user.dir") + File.separator + "target" + File.separator + "template-node"; private final File NULL_FILE = SystemUtils.IS_OS_WINDOWS ? new File("nul") : new File("/dev/null"); - + protected final String testClassName; + protected final String testMethodName; + protected final int[] portList; + private final int jmxPort; + private final String jmxUserName = "root"; + private final String jmxPassword = "passw!d"; + private final String TAB = " "; private Process instance; - protected final String testName; - - public AbstractNodeWrapper(String testName) { - this.testName = testName; - } - protected final String getId() { - return "node" + getPort(); + public AbstractNodeWrapper(String testClassName, String testMethodName) { + this.testClassName = testClassName; + this.testMethodName = testMethodName; + this.portList = searchAvailablePorts(); + jmxPort = this.portList[portList.length - 1]; } protected final int[] searchAvailablePorts() { @@ -141,7 +162,7 @@ public abstract class AbstractNodeWrapper implements BaseNodeWrapper { FileUtils.forceDelete(new File(getNodePath())); return; } catch (IOException ex) { - logger.error("Delete node dir failed. RetryTimes={}", i + 1, ex); + logger.warn("Delete node dir failed. RetryTimes={}", i + 1, ex); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { @@ -161,6 +182,7 @@ public abstract class AbstractNodeWrapper implements BaseNodeWrapper { .redirectOutput(stdoutFile) .redirectError(stdoutFile); this.instance = processBuilder.start(); + logger.info("In test {} {} started.", getTestLogDirName(), getId()); } catch (IOException ex) { fail("Start node failed. " + ex); } @@ -219,6 +241,12 @@ public abstract class AbstractNodeWrapper implements BaseNodeWrapper { try (FileWriter confOutput = new FileWriter(configPath)) { configProperties.store(confOutput, null); } + // Change JMX config + Path path = Paths.get(getEnvConfigPath()); + String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); + content = content.replaceAll("JMX_LOCAL=\"true\"", "JMX_LOCAL=\"false\""); + content = content.replaceAll("JMX_PORT=\"\\d+\"", String.format("JMX_PORT=\"%d\"", jmxPort)); + Files.write(path, content.getBytes(StandardCharsets.UTF_8)); } catch (IOException ex) { fail("Change the config of data node failed. " + ex); } @@ -246,15 +274,114 @@ public abstract class AbstractNodeWrapper implements BaseNodeWrapper { protected abstract String getConfigPath(); + protected abstract String getEnvConfigPath(); + protected abstract void updateConfig(Properties properties); protected abstract String getStartScriptPath(); protected abstract String getStopScriptPath(); - protected abstract String getLogPath(); + private String getLogPath() { + return getLogDirPath() + File.separator + getId() + ".log"; + } + + private String getLogDirPath() { + return System.getProperty("user.dir") + + File.separator + + "target" + + File.separator + + "cluster-logs" + + File.separator + + getTestLogDirName(); + } - protected String getNodePath() { + private String getNodePath() { return System.getProperty("user.dir") + File.separator + "target" + File.separator + getId(); } + + @Override + public void dumpJVMSnapshot(String testCaseName) { + JMXServiceURL url; + try { + url = + new JMXServiceURL( + String.format("service:jmx:rmi:///jndi/rmi://127.0.0.1:%d/jmxrmi", jmxPort)); + } catch (MalformedURLException e) { + logger.error("Construct JMX URL failed", e); + return; + } + Map<String, Object> environment = + Collections.singletonMap(JMXConnector.CREDENTIALS, new String[] {jmxUserName, jmxPassword}); + + try (JMXConnector connector = JMXConnectorFactory.connect(url, environment)) { + MBeanServerConnection mbsc = connector.getMBeanServerConnection(); + ThreadMXBean tmbean = + ManagementFactory.newPlatformMXBeanProxy( + mbsc, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class); + ThreadInfo[] threadInfos = tmbean.dumpAllThreads(true, true); + long[] deadlockIds = tmbean.findDeadlockedThreads(); + LocalDateTime currentTime = LocalDateTime.now(); + try (PrintWriter output = + new PrintWriter( + getLogDirPath() + File.separator + testCaseName + "_" + getId() + "-threads.dump")) { + output.printf("# Captured at %s\n", currentTime); + output.println("==================\n"); + if (deadlockIds != null && deadlockIds.length > 0) { + output.printf("Detect DEADLOCK threads!\n"); + for (long deadlockId : deadlockIds) { + ThreadInfo ti = tmbean.getThreadInfo(deadlockId); + output.printf("%s #%d\n", ti.getThreadName(), ti.getThreadId()); + } + output.println("==================\n"); + } + for (ThreadInfo threadInfo : threadInfos) { + dumpThread(output, threadInfo); + } + } + } catch (IOException e) { + logger.error("Connect with MBeanServer {} failed", url.getURLPath(), e); + } + } + + private void dumpThread(PrintWriter output, ThreadInfo ti) { + StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\""); + sb.append(" #").append(ti.getThreadId()); + sb.append(" ").append(ti.getThreadState()).append("\n"); + if (ti.getLockName() != null) { + sb.append("Waiting on: ").append(ti.getLockName()).append("\n"); + } + if (ti.getLockOwnerName() != null) { + sb.append("Locked by: ") + .append(ti.getLockOwnerName()) + .append(" #") + .append(ti.getLockOwnerId()) + .append("\n"); + } + Map<StackTraceElement, MonitorInfo> lockInfoMap = new HashMap<>(); + for (MonitorInfo monitor : ti.getLockedMonitors()) { + lockInfoMap.put(monitor.getLockedStackFrame(), monitor); + } + for (StackTraceElement ele : ti.getStackTrace()) { + if (lockInfoMap.containsKey(ele)) { + MonitorInfo monitorInfo = lockInfoMap.get(ele); + sb.append(TAB) + .append("- lock ") + .append(monitorInfo.getClassName()) + .append("@") + .append(Integer.toHexString(monitorInfo.getIdentityHashCode())) + .append("\n"); + } + sb.append(TAB).append(ele).append("\n"); + } + sb.append("\n"); + output.print(sb); + } + + private String getTestLogDirName() { + if (testMethodName == null) { + return testClassName; + } + return testClassName + "_" + testMethodName; + } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/ConfigNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/ConfigNodeWrapper.java index cd3ff3b4ee..319e854847 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/ConfigNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/ConfigNodeWrapper.java @@ -27,14 +27,11 @@ public class ConfigNodeWrapper extends AbstractNodeWrapper { private final int consensusPort; private final String targetConfigNode; - private final int[] portList; - public ConfigNodeWrapper(boolean isSeed, String targetConfigNode, String testName) { - super(testName); - - portList = super.searchAvailablePorts(); + public ConfigNodeWrapper( + boolean isSeed, String targetConfigNode, String testClassName, String testMethodName) { + super(testClassName, testMethodName); this.consensusPort = portList[1]; - if (isSeed) { this.targetConfigNode = getIpAndPortString(); } else { @@ -67,6 +64,14 @@ public class ConfigNodeWrapper extends AbstractNodeWrapper { return workDirFilePath("confignode" + File.separator + "conf", "iotdb-confignode.properties"); } + @Override + protected String getEnvConfigPath() { + if (SystemUtils.IS_OS_WINDOWS) { + return workDirFilePath("confignode" + File.separator + "conf", "confignode-env.bat"); + } + return workDirFilePath("confignode" + File.separator + "conf", "confignode-env.sh"); + } + @Override protected String getStartScriptPath() { String scriptName = "start-confignode.sh"; @@ -86,31 +91,12 @@ public class ConfigNodeWrapper extends AbstractNodeWrapper { } @Override - protected String getLogPath() { - return System.getProperty("user.dir") - + File.separator - + "target" - + File.separator - + "cluster-logs" - + File.separator - + testName - + File.separator - + "Config" - + super.getId() - + ".log"; - } - - @Override - protected String getNodePath() { - return System.getProperty("user.dir") - + File.separator - + "target" - + File.separator - + super.getId(); + public int getPort() { + return portList[0]; } @Override - public int getPort() { - return portList[0]; + public final String getId() { + return "ConfigNode" + getPort(); } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/DataNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/DataNodeWrapper.java index 87779bd2be..cb03c31d07 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/DataNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/DataNodeWrapper.java @@ -26,17 +26,14 @@ import java.util.Properties; public class DataNodeWrapper extends AbstractNodeWrapper { private final String targetConfigNode; - private final int dataBlockManagerPort; private final int internalPort; private final int dataRegionConsensusPort; private final int schemaRegionConsensusPort; - private final int[] portList; - public DataNodeWrapper(String targetConfigNode, String testName) { - super(testName); + public DataNodeWrapper(String targetConfigNode, String testClassName, String testMethodName) { + super(testClassName, testMethodName); this.targetConfigNode = targetConfigNode; - portList = super.searchAvailablePorts(); this.dataBlockManagerPort = portList[1]; this.internalPort = portList[2]; this.dataRegionConsensusPort = portList[3]; @@ -65,6 +62,14 @@ public class DataNodeWrapper extends AbstractNodeWrapper { return workDirFilePath("datanode" + File.separator + "conf", "iotdb-engine.properties"); } + @Override + protected String getEnvConfigPath() { + if (SystemUtils.IS_OS_WINDOWS) { + return workDirFilePath("datanode" + File.separator + "conf", "iotdb-env.bat"); + } + return workDirFilePath("datanode" + File.separator + "conf", "iotdb-env.sh"); + } + @Override protected String getStartScriptPath() { String scriptName = "start-datanode.sh"; @@ -84,22 +89,12 @@ public class DataNodeWrapper extends AbstractNodeWrapper { } @Override - protected String getLogPath() { - return System.getProperty("user.dir") - + File.separator - + "target" - + File.separator - + "cluster-logs" - + File.separator - + testName - + File.separator - + "Data" - + super.getId() - + ".log"; + public int getPort() { + return portList[0]; } @Override - public int getPort() { - return portList[0]; + public final String getId() { + return "DataNode" + getPort(); } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/IoTDBTestRunner.java b/integration-test/src/main/java/org/apache/iotdb/it/env/IoTDBTestRunner.java index 433c7dc357..f160f8dfc4 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/IoTDBTestRunner.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/IoTDBTestRunner.java @@ -38,7 +38,7 @@ public class IoTDBTestRunner extends BlockJUnit4ClassRunner { protected void runChild(final FrameworkMethod method, RunNotifier notifier) { Description description = describeChild(method); logger.info("Run {}", description.getMethodName()); - EnvFactory.getEnv().setNextTestCaseName(description.getMethodName()); + EnvFactory.getEnv().setTestMethodName(description.getMethodName()); super.runChild(method, notifier); } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/RemoteServerEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/RemoteServerEnv.java index 4bf339f335..a9be62426f 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/RemoteServerEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/RemoteServerEnv.java @@ -105,7 +105,12 @@ public class RemoteServerEnv implements BaseEnv { return connection; } - public void setNextTestCaseName(String testCaseName) { + public void setTestMethodName(String testCaseName) { + // Do nothing + } + + @Override + public void dumpTestJVMSnapshot() { // Do nothing } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneDataNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneDataNodeWrapper.java index 21ab80b13f..fbf28139f5 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneDataNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneDataNodeWrapper.java @@ -24,8 +24,9 @@ import java.io.File; public class StandaloneDataNodeWrapper extends DataNodeWrapper { - public StandaloneDataNodeWrapper(String targetConfigNode, String testName) { - super(targetConfigNode, testName); + public StandaloneDataNodeWrapper( + String targetConfigNode, String testClassName, String testMethodName) { + super(targetConfigNode, testClassName, testMethodName); } @Override diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneOnMppEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneOnMppEnv.java index 0d7e0fad35..3ae22d9739 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneOnMppEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/StandaloneOnMppEnv.java @@ -21,21 +21,19 @@ package org.apache.iotdb.it.env; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; +import java.util.Collections; public class StandaloneOnMppEnv extends AbstractEnv { private static final Logger logger = LoggerFactory.getLogger(StandaloneOnMppEnv.class); - private void initEnvironment() throws InterruptedException { - super.dataNodeWrapperList = new ArrayList<>(); - final String testName = super.getTestClassName() + super.getNextTestCaseString(); - DataNodeWrapper dataNodeWrapper = new StandaloneDataNodeWrapper(null, testName); + private void initEnvironment() { + DataNodeWrapper dataNodeWrapper = + new StandaloneDataNodeWrapper(null, super.getTestClassName(), super.getTestMethodName()); dataNodeWrapper.createDir(); dataNodeWrapper.changeConfig(ConfigFactory.getConfig().getEngineProperties()); dataNodeWrapper.start(); - super.dataNodeWrapperList.add(dataNodeWrapper); - logger.info("In test " + testName + " DataNode " + dataNodeWrapper.getId() + " started."); + super.dataNodeWrapperList = Collections.singletonList(dataNodeWrapper); super.testWorking(); } @@ -46,7 +44,7 @@ public class StandaloneOnMppEnv extends AbstractEnv { } @Override - public void initBeforeTest() throws InterruptedException { + public void initBeforeTest() { logger.debug("=======start init test======="); initEnvironment(); } @@ -57,7 +55,7 @@ public class StandaloneOnMppEnv extends AbstractEnv { dataNodeWrapper.waitingToShutDown(); dataNodeWrapper.destroyDir(); } - super.nextTestCase = null; + super.testMethodName = null; } @Override diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseEnv.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseEnv.java index 5ed57e05b8..8e5650d44b 100644 --- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseEnv.java @@ -37,5 +37,7 @@ public interface BaseEnv { Connection getConnection(Constant.Version version) throws SQLException; - void setNextTestCaseName(String testCaseName); + void setTestMethodName(String testCaseName); + + void dumpTestJVMSnapshot(); } diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java index ecb2e1fc05..c1efb1f351 100644 --- a/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/itbase/env/BaseNodeWrapper.java @@ -38,5 +38,9 @@ public interface BaseNodeWrapper { int getPort(); + String getId(); + String getIpAndPortString(); + + void dumpJVMSnapshot(String testCaseName); } diff --git a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ParallelRequestDelegate.java b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ParallelRequestDelegate.java index 92b5b478bc..2fae21e56c 100644 --- a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ParallelRequestDelegate.java +++ b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ParallelRequestDelegate.java @@ -18,6 +18,8 @@ */ package org.apache.iotdb.itbase.runtime; +import org.apache.iotdb.it.env.EnvFactory; + import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -53,6 +55,7 @@ public class ParallelRequestDelegate<T> extends RequestDelegate<T> { } catch (ExecutionException e) { exceptions[i] = e; } catch (InterruptedException | TimeoutException e) { + EnvFactory.getEnv().dumpTestJVMSnapshot(); for (int j = i; j < getEndpoints().size(); j++) { resultFutures.get(j).cancel(true); } diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/env/StandaloneEnv.java b/integration-test/src/test/java/org/apache/iotdb/db/it/env/StandaloneEnv.java index efe6c728b2..dfc4d4fa9f 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/env/StandaloneEnv.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/env/StandaloneEnv.java @@ -87,7 +87,11 @@ public class StandaloneEnv implements BaseEnv { return null; } - public void setNextTestCaseName(String testCaseName) { + public void setTestMethodName(String testCaseName) { + // Do nothing + } + + public void dumpTestJVMSnapshot() { // Do nothing } }
