From 47b48ba72b509f79017292e9e9e83a9140681975 Mon Sep 17 00:00:00 2001 From: Corneil du Plessis Date: Mon, 23 Oct 2023 22:58:16 +0800 Subject: [PATCH] Improve AwaitUtils (#5511) * Ensure that logs that are unavailable don't throw exceptions but returns an empty string * Fix CTR duplicating properties on similar names. #5525 --- .../integration/test/util/AwaitUtils.java | 328 ++++++++++-------- 1 file changed, 174 insertions(+), 154 deletions(-) diff --git a/spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test/util/AwaitUtils.java b/spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test/util/AwaitUtils.java index 4c9182ba02..b423f96bca 100644 --- a/spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test/util/AwaitUtils.java +++ b/spring-cloud-dataflow-server/src/test/java/org/springframework/cloud/dataflow/integration/test/util/AwaitUtils.java @@ -32,158 +32,178 @@ * @author Corneil du Plessis */ public class AwaitUtils { - /** - * StreamLog will maintain the offset to the end of the log so that subsequent calls will retrieve the remainder. - */ - public static class StreamLog { - Stream stream; - int offset = 0; - String appName; - - public StreamLog(Stream stream) { - this.stream = stream; - setupOffset(false); - } - - public StreamLog(Stream stream, String appName) { - this.stream = stream; - this.appName = appName; - setupOffset(false); - } - public StreamLog(Stream stream, boolean atCurrentEnd) { - this.stream = stream; - setupOffset(atCurrentEnd); - } - - public StreamLog(Stream stream, String appName, boolean atCurrentEnd) { - this.stream = stream; - this.appName = appName; - setupOffset(atCurrentEnd); - } - - private void setupOffset(boolean atCurrentEnd) { - offset = 0; - if (atCurrentEnd) { - String log = extractLog(); - offset = log.length(); - Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); - } - } - - - public String logs() { - String log = extractLog(); - Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); - String result = log.length() > offset ? log.substring(offset) : log; - offset = log.length(); - Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); - return result; - } - - private String extractLog() { - String log; - if (StringUtils.hasText(appName)) { - StreamApplication application = new StreamApplication(appName); - log = stream.logs(application); - } else { - log = stream.logs(); - } - return log == null ? "" : log; - } - - public String getStatus() { - return stream.getStatus(); - } - - public String getName() { - return stream.getName(); - } - } - - public static StreamLog logOffset(Stream stream) { - return new StreamLog(stream); - } - - public static StreamLog logOffset(Stream stream, boolean atCurrentEnd) { - return new StreamLog(stream, atCurrentEnd); - } - - public static StreamLog logOffset(Stream stream, String app) { - return new StreamLog(stream, app); - } - - public static StreamLog logOffset(Stream stream, String app, boolean atCurrentEnd) { - return new StreamLog(stream, app, atCurrentEnd); - } - - private static final Logger logger = LoggerFactory.getLogger(AwaitUtils.class); - - public static boolean hasErrorInLog(StreamLog offset) { - return hasInLog(offset, " ERROR "); - } - - public static boolean hasInLog(StreamLog offset, String value) { - String log = offset.logs(); - String status = offset.getStatus(); - if (log.contains(value)) { - String msg = "hasInLog:" + value + ":" + offset.getName() + ":" + status + ":" + expand(linesBeforeAfter(log, value)); - if(value.contains("ERROR")) { - logger.error(msg); - } else { - logger.info(msg); - } - return true; - } else { - if (StringUtils.hasText(log)) { - logger.debug("hasInLog:{}:{}:{}:{}", value, offset.getName(), status, expand(log)); - } - return false; - } - } - - public static boolean hasRegexInLog(StreamLog offset, String regex) { - String log = offset.logs(); - String status = offset.getStatus(); - if (Pattern.matches(regex, log)) { - logger.info("hasRegexInLog:" + offset.getName() + ":" + status + ":" + expand(linesBeforeAfterRegex(log, regex))); - return true; - } else { - if (StringUtils.hasText(log)) { - logger.debug("hasRegexInLog:{}:{}:{}", offset.getName(), status, expand(log)); - } - return false; - } - } - - public static String expand(String log) { - return log.replace("\\t", "\t").replace("\\n", "\n").replace("\\r", "\r"); - } - - public static String linesBeforeAfter(String log, String match) { - int matchIndex = log.indexOf(match); - if (matchIndex > 0) { - String target = log.substring(matchIndex > 320 ? matchIndex - 320 : matchIndex); - int start = target.indexOf('\n'); - if (start < 0) { - start = 0; - } - return target.substring(start); - } - return log; - } - - public static String linesBeforeAfterRegex(String log, String regex) { - Pattern pattern = Pattern.compile(regex); - String[] sections = pattern.split(log); - int matchIndex = log.indexOf(sections.length > 1 ? sections[1] : sections[0]); - if (matchIndex > 0) { - String target = log.substring(matchIndex > 320 ? matchIndex - 320 : matchIndex); - int start = target.indexOf('\n'); - if (start < 0) { - start = 0; - } - return target.substring(start); - } - return log; - } + /** + * StreamLog will maintain the offset to the end of the log so that subsequent calls will retrieve the remainder. + */ + public static class StreamLog { + Stream stream; + + int offset = 0; + + String appName; + + public StreamLog(Stream stream) { + this.stream = stream; + setupOffset(false); + } + + public StreamLog(Stream stream, String appName) { + this.stream = stream; + this.appName = appName; + setupOffset(false); + } + + public StreamLog(Stream stream, boolean atCurrentEnd) { + this.stream = stream; + setupOffset(atCurrentEnd); + } + + public StreamLog(Stream stream, String appName, boolean atCurrentEnd) { + this.stream = stream; + this.appName = appName; + setupOffset(atCurrentEnd); + } + + private void setupOffset(boolean atCurrentEnd) { + offset = 0; + if (atCurrentEnd) { + String log = extractLog(); + offset = log.length(); + Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); + } + } + + + public String logs() { + try { + String log = extractLog(); + Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); + String result = log.length() > offset ? log.substring(offset) : log; + offset = log.length(); + Assert.isTrue(offset >= 0, "Expected offset >= 0 not " + offset); + return result; + } catch (Throwable x) { + logger.info("logs:exception:" + x); + } + return ""; + } + + private String extractLog() { + String log = null; + try { + if (StringUtils.hasText(appName)) { + StreamApplication application = new StreamApplication(appName); + log = stream.logs(application); + } else { + log = stream.logs(); + } + } catch (Throwable x) { + logger.info("extractLog:exception:" + x); + } + return log == null ? "" : log; + } + + public String getStatus() { + return stream.getStatus(); + } + + public String getName() { + return stream.getName(); + } + } + + public static StreamLog logOffset(Stream stream) { + return new StreamLog(stream); + } + + public static StreamLog logOffset(Stream stream, boolean atCurrentEnd) { + return new StreamLog(stream, atCurrentEnd); + } + + public static StreamLog logOffset(Stream stream, String app) { + return new StreamLog(stream, app); + } + + public static StreamLog logOffset(Stream stream, String app, boolean atCurrentEnd) { + return new StreamLog(stream, app, atCurrentEnd); + } + + private static final Logger logger = LoggerFactory.getLogger(AwaitUtils.class); + + public static boolean hasErrorInLog(StreamLog offset) { + return hasInLog(offset, " ERROR "); + } + + public static boolean hasInLog(StreamLog offset, String value) { + try { + String log = offset.logs(); + String status = offset.getStatus(); + if (log.contains(value)) { + String msg = "hasInLog:" + value + ":" + offset.getName() + ":" + status + ":" + expand(linesBeforeAfter(log, value)); + if (value.contains("ERROR")) { + logger.error(msg); + } else { + logger.info(msg); + } + return true; + } else { + if (StringUtils.hasText(log)) { + logger.debug("hasInLog:{}:{}:{}:{}", value, offset.getName(), status, expand(log)); + } + } + } catch (Throwable x) { + logger.debug("hasInLog:exception:" + x); + } + return false; + } + + public static boolean hasRegexInLog(StreamLog offset, String regex) { + try { + String log = offset.logs(); + String status = offset.getStatus(); + if (Pattern.matches(regex, log)) { + logger.info("hasRegexInLog:" + offset.getName() + ":" + status + ":" + expand(linesBeforeAfterRegex(log, regex))); + return true; + } else { + if (StringUtils.hasText(log)) { + logger.debug("hasRegexInLog:{}:{}:{}", offset.getName(), status, expand(log)); + } + } + } catch (Throwable x) { + logger.debug("hasRegexInLog:exception:" + x); + } + return false; + } + + public static String expand(String log) { + return log.replace("\\t", "\t").replace("\\n", "\n").replace("\\r", "\r"); + } + + public static String linesBeforeAfter(String log, String match) { + int matchIndex = log.indexOf(match); + if (matchIndex > 0) { + String target = log.substring(matchIndex > 320 ? matchIndex - 320 : matchIndex); + int start = target.indexOf('\n'); + if (start < 0) { + start = 0; + } + return target.substring(start); + } + return log; + } + + public static String linesBeforeAfterRegex(String log, String regex) { + Pattern pattern = Pattern.compile(regex); + String[] sections = pattern.split(log); + int matchIndex = log.indexOf(sections.length > 1 ? sections[1] : sections[0]); + if (matchIndex > 0) { + String target = log.substring(matchIndex > 320 ? matchIndex - 320 : matchIndex); + int start = target.indexOf('\n'); + if (start < 0) { + start = 0; + } + return target.substring(start); + } + return log; + } }