1 /* 2 * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.util.Arrays; 25 26 import jdk.internal.platform.Metrics; 27 import jdk.internal.platform.CgroupV1Metrics; 28 29 public class MetricsMemoryTester { 30 public static void main(String[] args) { 31 System.out.println(Arrays.toString(args)); 32 switch (args[0]) { 33 case "memory": 34 testMemoryLimit(args[1]); 35 break; 36 case "memoryswap": 37 testMemoryAndSwapLimit(args[1], args[2]); 38 break; 39 case "kernelmem": 40 testKernelMemoryLimit(args[1]); 41 break; 42 case "oomkill": 43 testOomKillFlag(Boolean.parseBoolean(args[2])); 44 break; 45 case "failcount": 46 testMemoryFailCount(); 47 break; 48 case "softlimit": 49 testMemorySoftLimit(args[1]); 50 break; 51 } 52 } 53 54 private static void testMemoryLimit(String value) { 55 long limit = getMemoryValue(value); 56 57 if (limit != Metrics.systemMetrics().getMemoryLimit()) { 58 throw new RuntimeException("Memory limit not equal, expected : [" 59 + limit + "]" + ", got : [" 60 + Metrics.systemMetrics().getMemoryLimit() + "]"); 61 } 62 System.out.println("TEST PASSED!!!"); 63 } 64 65 private static void testMemoryFailCount() { 66 long count = Metrics.systemMetrics().getMemoryFailCount(); 67 68 // Allocate 512M of data 69 byte[][] bytes = new byte[64][]; 70 boolean atLeastOneAllocationWorked = false; 71 for (int i = 0; i < 64; i++) { 72 try { 73 bytes[i] = new byte[8 * 1024 * 1024]; 74 atLeastOneAllocationWorked = true; 75 // Break out as soon as we see an increase in failcount 76 // to avoid getting killed by the OOM killer. 77 if (Metrics.systemMetrics().getMemoryFailCount() > count) { 78 break; 79 } 80 } catch (Error e) { // OOM error 81 break; 82 } 83 } 84 if (!atLeastOneAllocationWorked) { 85 System.out.println("Allocation failed immediately. Ignoring test!"); 86 return; 87 } 88 // Be sure bytes allocations don't get optimized out 89 System.out.println("DEBUG: Bytes allocation length 1: " + bytes[0].length); 90 if (Metrics.systemMetrics().getMemoryFailCount() <= count) { 91 throw new RuntimeException("Memory fail count : new : [" 92 + Metrics.systemMetrics().getMemoryFailCount() + "]" 93 + ", old : [" + count + "]"); 94 } 95 System.out.println("TEST PASSED!!!"); 96 } 97 98 private static void testMemorySoftLimit(String softLimit) { 99 100 long memorySoftLimit = Metrics.systemMetrics().getMemorySoftLimit(); 101 long newmemorySoftLimit = getMemoryValue(softLimit); 102 103 if (newmemorySoftLimit != memorySoftLimit) { 104 throw new RuntimeException("Memory softlimit not equal, Actual : [" 105 + newmemorySoftLimit + "]" + ", Expected : [" 106 + memorySoftLimit + "]"); 107 } 108 System.out.println("TEST PASSED!!!"); 109 } 110 111 private static void testKernelMemoryLimit(String value) { 112 Metrics m = Metrics.systemMetrics(); 113 if (m instanceof CgroupV1Metrics) { 114 CgroupV1Metrics mCgroupV1 = (CgroupV1Metrics)m; 115 System.out.println("TEST PASSED!!!"); 116 long limit = getMemoryValue(value); 117 long kmemlimit = mCgroupV1.getKernelMemoryLimit(); 118 if (kmemlimit != 0 && limit != kmemlimit) { 119 throw new RuntimeException("Kernel Memory limit not equal, expected : [" 120 + limit + "]" + ", got : [" 121 + kmemlimit + "]"); 122 } 123 } else { 124 throw new RuntimeException("oomKillFlag test not supported for cgroups v2"); 125 } 126 } 127 128 private static void testMemoryAndSwapLimit(String memory, String memAndSwap) { 129 long expectedMem = getMemoryValue(memory); 130 long expectedMemAndSwap = getMemoryValue(memAndSwap); 131 132 if (expectedMem != Metrics.systemMetrics().getMemoryLimit() 133 || expectedMemAndSwap != Metrics.systemMetrics().getMemoryAndSwapLimit()) { 134 System.err.println("Memory and swap limit not equal, expected : [" 135 + expectedMem + ", " + expectedMemAndSwap + "]" 136 + ", got : [" + Metrics.systemMetrics().getMemoryLimit() 137 + ", " + Metrics.systemMetrics().getMemoryAndSwapLimit() + "]"); 138 } 139 System.out.println("TEST PASSED!!!"); 140 } 141 142 private static long getMemoryValue(String value) { 143 long result; 144 if (value.endsWith("m")) { 145 result = Long.parseLong(value.substring(0, value.length() - 1)) 146 * 1024 * 1024; 147 } else if (value.endsWith("g")) { 148 result = Long.parseLong(value.substring(0, value.length() - 1)) 149 * 1024 * 1024 * 1024; 150 } else { 151 result = Long.parseLong(value); 152 } 153 return result; 154 } 155 156 private static void testOomKillFlag(boolean oomKillFlag) { 157 Metrics m = Metrics.systemMetrics(); 158 if (m instanceof CgroupV1Metrics) { 159 CgroupV1Metrics mCgroupV1 = (CgroupV1Metrics)m; 160 Boolean expected = Boolean.valueOf(oomKillFlag); 161 Boolean actual = mCgroupV1.isMemoryOOMKillEnabled(); 162 if (!(expected.equals(actual))) { 163 throw new RuntimeException("oomKillFlag error"); 164 } 165 System.out.println("TEST PASSED!!!"); 166 } else { 167 throw new RuntimeException("oomKillFlag test not supported for cgroups v2"); 168 } 169 } 170 }