diff --git a/mo.yml b/mo.yml index e86a415ea..29682d0c1 100755 --- a/mo.yml +++ b/mo.yml @@ -6,7 +6,7 @@ jdbc: #- addr: "127.0.0.1:3306" #- addr: "127.0.0.1:3306" database: - default: "" + default: "test" paremeter: characterSetResults: "utf8" continueBatchOnError: "false" diff --git a/src/main/java/io/mo/cases/SqlCommand.java b/src/main/java/io/mo/cases/SqlCommand.java index f6e78c320..3e9d2089a 100755 --- a/src/main/java/io/mo/cases/SqlCommand.java +++ b/src/main/java/io/mo/cases/SqlCommand.java @@ -95,6 +95,18 @@ public class SqlCommand { @Getter @Setter private int sleeptime = 0; + + @Getter + @Setter + private boolean waitExpect = false; + + @Getter + @Setter + private int waitExpectInterval = 0; + + @Getter + @Setter + private int waitExpectTimeout = 0; @Getter @Setter @@ -154,6 +166,10 @@ public void setActResult(StmtResult actResult) { } } + public StmtResult getActResult() { + return actResult; + } + public boolean checkResult() { // Check if regex patterns are set if (this.regexPatterns != null && !this.regexPatterns.isEmpty()) { diff --git a/src/main/java/io/mo/constant/COMMON.java b/src/main/java/io/mo/constant/COMMON.java index 687c4b3c6..b17d07399 100755 --- a/src/main/java/io/mo/constant/COMMON.java +++ b/src/main/java/io/mo/constant/COMMON.java @@ -22,6 +22,7 @@ public class COMMON { public static String NEW_SESSION_END_FLAG = "-- @session"; public static String BVT_SKIP_FILE_FLAG = "-- @skip:issue#"; public static String FUNC_SLEEP_FLAG = "-- @sleep:"; + public static String WAIT_EXPECT_FLAG = "-- @wait_expect"; public static String BVT_ISSUE_START_FLAG = "-- @bvt:issue#"; public static String BVT_ISSUE_END_FLAG = "-- @bvt:issue"; public static String SORT_KEY_INDEX_FLAG = "-- @sortkey:"; @@ -89,4 +90,4 @@ public class COMMON { public static double SCALE_TOLERABLE_ERROR = 0.0000009; public static double INT_TOLERABLE_ERROR = 0.000000000000001; -} \ No newline at end of file +} diff --git a/src/main/java/io/mo/db/Executor.java b/src/main/java/io/mo/db/Executor.java index 7fb237eba..351d64790 100755 --- a/src/main/java/io/mo/db/Executor.java +++ b/src/main/java/io/mo/db/Executor.java @@ -223,6 +223,46 @@ public void run(TestScript script) { command.setActResult(actResult); } + if (command.isWaitExpect()) { + int intervalMs = command.getWaitExpectInterval() * 1000; + int timeoutMs = command.getWaitExpectTimeout() * 1000; + if (intervalMs > 0 && timeoutMs > 0) { + StmtResult firstActResult = command.getActResult(); + if (firstActResult == null || firstActResult.getType() != RESULT.STMT_RESULT_TYPE_SET) { + logger.warn(String.format( + "wait_expect is only safe for query results. Skip retry for command[%s][row:%d].", + command.getCommand(), command.getPosition())); + } else { + long deadline = System.currentTimeMillis() + timeoutMs; + boolean matched = command.checkResult(); + while (!matched && System.currentTimeMillis() < deadline) { + long now = System.currentTimeMillis(); + long sleepMs = Math.min(intervalMs, Math.max(0, deadline - now)); + if (sleepMs > 0) { + Thread.sleep(sleepMs); + } + if (statement != null) { + statement.close(); + } + statement = connection.createStatement(); + statement.execute(sqlCmd); + ResultSet retryResultSet = statement.getResultSet(); + if (retryResultSet != null) { + RSSet rsSet = new RSSet(retryResultSet, command); + StmtResult actResult = new StmtResult(rsSet); + command.setActResult(actResult); + command.getTestResult().setActResult(actResult.toString()); + } else { + StmtResult actResult = new StmtResult(); + actResult.setType(RESULT.STMT_RESULT_TYPE_NONE); + command.setActResult(actResult); + } + matched = command.checkResult(); + } + } + } + } + checkResult(command, script); statement.close(); @@ -381,6 +421,11 @@ public boolean genRS(TestScript script) { statement = connection.createStatement(); String sqlCmd = command.getCommand().replaceAll("\\$resources", COMMON.RESOURCE_PATH); + if (command.isWaitExpect() && command.getWaitExpectTimeout() > 0) { + logger.info(String.format("The tester will wait_expect for %s s before generating result, please wait....", + command.getWaitExpectTimeout())); + Thread.sleep(command.getWaitExpectTimeout() * 1000L); + } if (command.isNeedWait()) { execWaitOperation(command); } diff --git a/src/main/java/io/mo/util/ScriptParser.java b/src/main/java/io/mo/util/ScriptParser.java index 7408dee8a..2d105fc29 100755 --- a/src/main/java/io/mo/util/ScriptParser.java +++ b/src/main/java/io/mo/util/ScriptParser.java @@ -101,6 +101,8 @@ private boolean processCommentLine(String trimmedLine, String path, SqlCommand c // Simple flag handlers if (trimmedLine.startsWith(COMMON.FUNC_SLEEP_FLAG)) { command.setSleeptime(Integer.parseInt(trimmedLine.substring(COMMON.FUNC_SLEEP_FLAG.length()))); + } else if (trimmedLine.startsWith(COMMON.WAIT_EXPECT_FLAG)) { + parseWaitExpectFlag(trimmedLine, command); } else if (trimmedLine.startsWith(COMMON.SYSTEM_CMD_FLAG)) { command.addSysCMD(trimmedLine.substring(COMMON.SYSTEM_CMD_FLAG.length())); } else if (trimmedLine.startsWith(COMMON.REGULAR_MATCH_FLAG)) { @@ -155,6 +157,43 @@ private void parseWaitFlag(String trimmedLine, SqlCommand command) { command.setNeedWait(true); } + private void parseWaitExpectFlag(String trimmedLine, SqlCommand command) { + String rest = trimmedLine.substring(COMMON.WAIT_EXPECT_FLAG.length()).trim(); + if (!rest.startsWith("(") || !rest.endsWith(")")) { + LOG.warn(String.format("Invalid wait_expect flag format: %s. Expected -- @wait_expect(interval, timeout)", trimmedLine)); + return; + } + + String content = rest.substring(1, rest.length() - 1); + String[] parts = content.split(","); + if (parts.length != 2) { + LOG.warn(String.format("Invalid wait_expect flag format: %s. Expected -- @wait_expect(interval, timeout)", trimmedLine)); + return; + } + + String intervalStr = parts[0].trim(); + String timeoutStr = parts[1].trim(); + if (!StringUtils.isNumeric(intervalStr) || !StringUtils.isNumeric(timeoutStr)) { + LOG.warn(String.format("Invalid wait_expect flag values: %s. Interval/timeout must be numeric.", trimmedLine)); + return; + } + + int interval = Integer.parseInt(intervalStr); + int timeout = Integer.parseInt(timeoutStr); + if (interval <= 0 || timeout <= 0) { + LOG.warn(String.format("Invalid wait_expect flag values: %s. Interval/timeout must be > 0.", trimmedLine)); + return; + } + if (interval > timeout) { + LOG.warn(String.format("wait_expect interval(%d) is greater than timeout(%d), interval will be capped to timeout.", interval, timeout)); + interval = timeout; + } + + command.setWaitExpect(true); + command.setWaitExpectInterval(interval); + command.setWaitExpectTimeout(timeout); + } + private void parseConnectionInfo(String trimmedLine, ConnectionInfo conInfo, String path, int rowNum) { String conInfoStr = trimmedLine.endsWith("{") ? trimmedLine.substring(COMMON.NEW_SESSION_START_FLAG.length(), trimmedLine.length() - 1) @@ -519,4 +558,3 @@ public static void main(String[] args){ } } -