|
3 | 3 | import org.junit.jupiter.api.BeforeAll; |
4 | 4 | import org.junit.jupiter.api.Test; |
5 | 5 |
|
| 6 | +import java.lang.management.ManagementFactory; |
6 | 7 | import java.util.Collections; |
| 8 | +import java.util.List; |
7 | 9 | import java.util.concurrent.atomic.AtomicBoolean; |
8 | 10 | import java.util.concurrent.atomic.AtomicReference; |
9 | 11 |
|
@@ -77,10 +79,40 @@ void testGetFlag() { |
77 | 79 | // The test relies on the gradle test task setting the JVM flags to expected values |
78 | 80 | assertEquals("build/hs_err_pid%p.log", flags.getStringFlag("ErrorFile")); // set to 'build/hs_err_pid%p.log' in the test task |
79 | 81 | assertTrue(flags.getBooleanFlag("ResizeTLAB")); // set to 'true' in the test task |
80 | | - assertEquals(512 * 1024 * 1024, flags.getIntFlag("MaxHeapSize")); // set to 512m in the test task |
| 82 | + // Derive the expected heap from this JVM's own -Xmx argument rather than hardcoding a |
| 83 | + // value, so the test stays valid regardless of what the build task passes per config. |
| 84 | + assertEquals(configuredMaxHeapBytes(), flags.getIntFlag("MaxHeapSize")); |
81 | 85 | assertNotNull(flags.getStringFlag("OnError")); |
82 | 86 | } |
83 | 87 |
|
| 88 | + private static long configuredMaxHeapBytes() { |
| 89 | + // HotSpot honors the last -Xmx flag on the command line when duplicates are |
| 90 | + // present (e.g. ASan configs append a config-specific -Xmx after the |
| 91 | + // standard one), so scan from the end to find the effective value. |
| 92 | + List<String> jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); |
| 93 | + for (int i = jvmArgs.size() - 1; i >= 0; i--) { |
| 94 | + String arg = jvmArgs.get(i); |
| 95 | + if (arg.startsWith("-Xmx")) { |
| 96 | + return parseMemorySize(arg.substring("-Xmx".length())); |
| 97 | + } |
| 98 | + } |
| 99 | + throw new IllegalStateException("Test JVM was not launched with -Xmx: " + jvmArgs); |
| 100 | + } |
| 101 | + |
| 102 | + private static long parseMemorySize(String value) { |
| 103 | + try { |
| 104 | + char unit = Character.toLowerCase(value.charAt(value.length() - 1)); |
| 105 | + switch (unit) { |
| 106 | + case 'k': return Long.parseLong(value.substring(0, value.length() - 1)) * 1024L; |
| 107 | + case 'm': return Long.parseLong(value.substring(0, value.length() - 1)) * 1024L * 1024L; |
| 108 | + case 'g': return Long.parseLong(value.substring(0, value.length() - 1)) * 1024L * 1024L * 1024L; |
| 109 | + default: return Long.parseLong(value); |
| 110 | + } |
| 111 | + } catch (NumberFormatException e) { |
| 112 | + throw new IllegalArgumentException("Invalid -Xmx memory size: " + value, e); |
| 113 | + } |
| 114 | + } |
| 115 | + |
84 | 116 | @Test |
85 | 117 | void testGetFlagMismatch() { |
86 | 118 | JVMAccess.Flags flags = JVMAccess.getInstance().flags(); |
|
0 commit comments