From 62dca46d20cf8b9d3f394a53988c0460cae8211a Mon Sep 17 00:00:00 2001 From: Kerem Kat Date: Thu, 17 Oct 2024 11:25:57 +0100 Subject: [PATCH] Simplify java assertions and add messages to all (#1027) --- test/one/profiler/test/Assert.java | 87 ++++++++++++++++++-------- test/one/profiler/test/SourceCode.java | 57 +++++++++++++++++ test/test/lock/LockTests.java | 3 +- 3 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 test/one/profiler/test/SourceCode.java diff --git a/test/one/profiler/test/Assert.java b/test/one/profiler/test/Assert.java index e347c3c8c..8ed634b2f 100644 --- a/test/one/profiler/test/Assert.java +++ b/test/one/profiler/test/Assert.java @@ -5,49 +5,86 @@ package one.profiler.test; +import java.util.function.BiPredicate; import java.util.logging.Level; import java.util.logging.Logger; public class Assert { - private static final Logger log = Logger.getLogger(Assert.class.getName()); + enum Comparison { + GT(">", (a, b) -> a > b), + GTE(">=", (a, b) -> a >= b), + LT("<", (a, b) -> a < b), + LTE("<=", (a, b) -> a <= b), + EQ("==", Double::equals), + NE("!=", (a, b) -> !Double.isNaN(a) && !Double.isNaN(b) && !a.equals(b)); + + public final String operator; + public final BiPredicate comparator; - public static void isGreater(double value, double threshold) { - isGreater(value, threshold, null); + Comparison(String operator, BiPredicate comparator) { + this.operator = operator; + this.comparator = comparator; + } } - public static void isGreater(double value, double threshold, String message) { - boolean asserted = value <= threshold; - log.log(Level.FINE, "isGreater (asserted: " + asserted + ") " + (message == null ? "" : message) + ": " + value + " > " + threshold); + private static final Logger log = Logger.getLogger(Assert.class.getName()); + + private static void assertComparison(Comparison comparison, double left, double right, @SuppressWarnings("unused") String message) { + boolean asserted = !comparison.comparator.test(left, right); + // message parameter will be part of the source code line. + String assertionMessage = String.format("%s %s %s\n%s", left, comparison.operator, right, SourceCode.tryGet(2)); + log.log(Level.FINE, String.format("isAsserted %s: %s", asserted, assertionMessage)); if (asserted) { - throw new AssertionError( - "Expected " + value + " > " + threshold + (message != null ? (": " + message) : "")); + throw new AssertionError("Expected " + assertionMessage); } } - public static void isGreaterOrEqual(double value, double threshold) { - if (value < threshold) { - throw new AssertionError("Expected " + value + " >= " + threshold); - } + public static void isEqual(double left, double right) { + assertComparison(Comparison.EQ, left, right, null); } - public static void isLess(double value, double threshold) { - isLess(value, threshold, null); + public static void isEqual(double left, double right, String message) { + assertComparison(Comparison.EQ, left, right, message); } - public static void isLess(double value, double threshold, String message) { - boolean asserted = value >= threshold; - log.log(Level.FINE, "isLess (asserted: " + asserted + ")" + (message == null ? "" : message) + ": " + value + " < " + threshold); + public static void isNotEqual(double left, double right) { + assertComparison(Comparison.NE, left, right, null); + } - if (asserted) { - throw new AssertionError( - "Expected " + value + " < " + threshold + (message != null ? (": " + message) : "")); - } + public static void isNotEqual(double left, double right, String message) { + assertComparison(Comparison.NE, left, right, message); } - public static void isLessOrEqual(double value, double threshold) { - if (value > threshold) { - throw new AssertionError("Expected " + value + " <= " + threshold); - } + public static void isGreater(double left, double right) { + assertComparison(Comparison.GT, left, right, null); + } + + public static void isGreater(double left, double right, String message) { + assertComparison(Comparison.GT, left, right, message); + } + + public static void isGreaterOrEqual(double left, double right) { + assertComparison(Comparison.GTE, left, right, null); + } + + public static void isGreaterOrEqual(double left, double right, String message) { + assertComparison(Comparison.GTE, left, right, message); + } + + public static void isLess(double left, double right) { + assertComparison(Comparison.LT, left, right, null); + } + + public static void isLess(double left, double right, String message) { + assertComparison(Comparison.LT, left, right, message); + } + + public static void isLessOrEqual(double left, double right) { + assertComparison(Comparison.LTE, left, right, null); + } + + public static void isLessOrEqual(double left, double right, String message) { + assertComparison(Comparison.LTE, left, right, message); } } diff --git a/test/one/profiler/test/SourceCode.java b/test/one/profiler/test/SourceCode.java new file mode 100644 index 000000000..9620b5f32 --- /dev/null +++ b/test/one/profiler/test/SourceCode.java @@ -0,0 +1,57 @@ +/* + * Copyright The async-profiler authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package one.profiler.test; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +public class SourceCode { + public static String tryGet(int ignoreFrames) { + return tryGet(new Exception(), ignoreFrames + 1); + } + + public static String tryGet(Throwable e, int ignoreFrames) { + StackTraceElement[] stackTrace = e.getStackTrace(); + + if (stackTrace.length > ignoreFrames) { + StackTraceElement element = stackTrace[ignoreFrames]; + String className = element.getClassName(); + String filePath = getFilePath(className); + + return getSourceCodeAt(filePath, element.getLineNumber()); + } + return "No stack trace available"; + } + + private static String getFilePath(String className) { + int dollar = className.lastIndexOf('$'); + if (dollar >= 0) { + className = className.substring(0, dollar); + } + return "test/" + className.replace('.', '/') + ".java"; + } + + private static String getSourceCodeAt(String filePath, int lineNumber) { + String result = "\t> " + filePath + ":" + lineNumber; + + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + String line; + int currentLine = 1; + + while ((line = reader.readLine()) != null) { + if (currentLine == lineNumber) { + return result + "\n\t> " + line.trim(); + } + currentLine++; + } + } catch (IOException ex) { + return "Error reading source file: " + ex.getMessage(); + } + + return result; + } +} diff --git a/test/test/lock/LockTests.java b/test/test/lock/LockTests.java index d9f81cd5d..852bc5505 100644 --- a/test/test/lock/LockTests.java +++ b/test/test/lock/LockTests.java @@ -12,7 +12,7 @@ public class LockTests { - @Test(mainClass = DatagramTest.class, debugNonSafepoints = true) // Fails on Alpine + @Test(mainClass = DatagramTest.class, debugNonSafepoints = true) public void datagramSocketLock(TestProcess p) throws Exception { Output out = p.profile("-e cpu -d 3 -o collapsed --cstack dwarf"); assert out.ratio("(PlatformEvent::.ark|PlatformEvent::.npark)") > 0.1 @@ -26,7 +26,6 @@ public void datagramSocketLock(TestProcess p) throws Exception { @Test(mainClass = RaceToLock.class, inputs = "1000000", output = true) public void raceToLocks(TestProcess p) throws Exception { int interval = Integer.parseInt(p.inputs()[0]); - Output out = p.profile("--lock " + interval + " --threads -o collapsed"); Output stdout = p.readFile(TestProcess.STDOUT);