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 import jdk.internal.platform.Metrics; 26 import jdk.internal.platform.MetricsCgroupV1; 27 28 public class MetricsMemoryTester { 29 public static void main(String[] args) { 30 System.out.println(Arrays.toString(args)); 31 switch (args[0]) { 32 case "memory": 33 testMemoryLimit(args[1]); 34 break; 35 case "memoryswap": 36 testMemoryAndSwapLimit(args[1], args[2]); 37 break; 38 case "kernelmem": 39 testKernelMemoryLimit(args[1]); 40 break; 41 case "oomkill": 42 testOomKillFlag(Boolean.parseBoolean(args[2])); 43 break; 44 case "failcount": 45 testMemoryFailCount(); 46 break; 47 case "softlimit": 48 testMemorySoftLimit(args[1]); 49 break; 50 } 51 } 52 53 private static void testMemoryLimit(String value) { 54 long limit = getMemoryValue(value); 55 56 if (limit != Metrics.systemMetrics().getMemoryLimit()) { 57 throw new RuntimeException("Memory limit not equal, expected : [" 58 + limit + "]" + ", got : [" 59 + Metrics.systemMetrics().getMemoryLimit() + "]"); 60 } 61 System.out.println("TEST PASSED!!!"); 62 } 63 64 private static void testMemoryFailCount() { 65 long count = Metrics.systemMetrics().getMemoryFailCount(); 66 67 // Allocate 512M of data 68 byte[][] bytes = new byte[64][]; 69 boolean atLeastOneAllocationWorked = false; 70 for (int i = 0; i < 64; i++) { 71 try { 72 bytes[i] = new byte[8 * 1024 * 1024]; 73 atLeastOneAllocationWorked = true; 74 // Break out as soon as we see an increase in failcount 75 // to avoid getting killed by the OOM killer. 76 if (Metrics.systemMetrics().getMemoryFailCount() > count) { 77 break; 78 } 79 } catch (Error e) { // OOM error 80 break; 81 } 82 } 83 if (!atLeastOneAllocationWorked) { 84 System.out.println("Allocation failed immediately. Ignoring test!"); 85 return; 86 } 87 // Be sure bytes allocations don't get optimized out 88 System.out.println("DEBUG: Bytes allocation length 1: " + bytes[0].length); 89 if (Metrics.systemMetrics().getMemoryFailCount() <= count) { 90 throw new RuntimeException("Memory fail count : new : [" 91 + Metrics.systemMetrics().getMemoryFailCount() + "]" 92 + ", old : [" + count + "]"); 93 } 94 System.out.println("TEST PASSED!!!"); 95 } 96 97 private static void testMemorySoftLimit(String softLimit) { 98 99 long memorySoftLimit = Metrics.systemMetrics().getMemorySoftLimit(); 100 long newmemorySoftLimit = getMemoryValue(softLimit); 101 102 if (newmemorySoftLimit != memorySoftLimit) { 103 throw new RuntimeException("Memory softlimit not equal, Actual : [" 104 + newmemorySoftLimit + "]" + ", Expected : [" 105 + memorySoftLimit + "]"); 106 } 107 System.out.println("TEST PASSED!!!"); 108 } 109 110 private static void testKernelMemoryLimit(String value) { 111 Metrics m = Metrics.systemMetrics(); 112 if (m instanceof MetricsCgroupV1) { 113 MetricsCgroupV1 mCgroupV1 = (MetricsCgroupV1)m; 114 System.out.println("TEST PASSED!!!"); 115 long limit = getMemoryValue(value); 116 long kmemlimit = mCgroupV1.getKernelMemoryLimit(); 117 if (kmemlimit != 0 && limit != kmemlimit) { 118 throw new RuntimeException("Kernel Memory limit not equal, expected : [" 119 + limit + "]" + ", got : [" 120 + kmemlimit + "]"); 121 } 122 } else { 123 throw new RuntimeException("oomKillFlag test not supported for cgroups v2"); 124 } 125 } 126 127 private static void testMemoryAndSwapLimit(String memory, String memAndSwap) { 128 long expectedMem = getMemoryValue(memory); 129 long expectedMemAndSwap = getMemoryValue(memAndSwap); 130 131 if (expectedMem != Metrics.systemMetrics().getMemoryLimit() 132 || expectedMemAndSwap != Metrics.systemMetrics().getMemoryAndSwapLimit()) { 133 System.err.println("Memory and swap limit not equal, expected : [" 134 + expectedMem + ", " + expectedMemAndSwap + "]" 135 + ", got : [" + Metrics.systemMetrics().getMemoryLimit() 136 + ", " + Metrics.systemMetrics().getMemoryAndSwapLimit() + "]"); 137 } 138 System.out.println("TEST PASSED!!!"); 139 } 140 141 private static long getMemoryValue(String value) { 142 long result; 143 if (value.endsWith("m")) { 144 result = Long.parseLong(value.substring(0, value.length() - 1)) 145 * 1024 * 1024; 146 } else if (value.endsWith("g")) { 147 result = Long.parseLong(value.substring(0, value.length() - 1)) 148 * 1024 * 1024 * 1024; 149 } else { 150 result = Long.parseLong(value); 151 } 152 return result; 153 } 154 155 private static void testOomKillFlag(boolean oomKillFlag) { 156 Metrics m = Metrics.systemMetrics(); 157 if (m instanceof MetricsCgroupV1) { 158 MetricsCgroupV1 mCgroupV1 = (MetricsCgroupV1)m; 159 Boolean expected = Boolean.valueOf(oomKillFlag); 160 Boolean actual = mCgroupV1.isMemoryOOMKillEnabled(); 161 if (!(expected.equals(actual))) { 162 throw new RuntimeException("oomKillFlag error"); 163 } 164 System.out.println("TEST PASSED!!!"); 165 } else { 166 throw new RuntimeException("oomKillFlag test not supported for cgroups v2"); 167 } 168 } 169 }