1 /* 2 * Copyright (c) 2018, 2019, 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 package jdk.test.lib.containers.cgroup; 25 26 import java.io.File; 27 import java.io.FileNotFoundException; 28 import java.io.IOException; 29 import java.nio.file.Files; 30 import java.nio.file.Path; 31 import java.nio.file.Paths; 32 import java.util.Arrays; 33 import java.util.HashMap; 34 import java.util.Map; 35 import java.util.Scanner; 36 import java.util.Set; 37 import java.util.stream.Collectors; 38 import java.util.stream.LongStream; 39 import java.util.stream.Stream; 40 41 import jdk.internal.platform.Metrics; 42 43 public class MetricsTesterCgroupV1 implements CgroupMetricsTester { 44 45 private static long unlimited_minimum = 0x7FFFFFFFFF000000L; 46 long startSysVal; 47 long startUserVal; 48 long startUsage; 49 long startPerCpu[]; 50 51 enum Controller { 52 MEMORY("memory"), 53 CPUSET("cpuset"), 54 CPU("cpu"), 55 CPUACCT("cpuacct"), 56 BLKIO("blkio"); 57 58 private String value; 59 60 Controller(String value) { 61 this.value = value; 62 } 63 64 public String value() { 65 return value; 66 } 67 } 68 69 private static final Set<String> allowedSubSystems = 70 Stream.of(Controller.values()).map(Controller::value).collect(Collectors.toSet()); 71 72 private static final Map<String, String[]> subSystemPaths = new HashMap<>(); 73 74 private static void setPath(String[] line) { 75 String cgroupPath = line[2]; 76 String[] subSystems = line[1].split(","); 77 78 for (String subSystem : subSystems) { 79 if (allowedSubSystems.contains(subSystem)) { 80 String[] paths = subSystemPaths.get(subSystem); 81 String finalPath = ""; 82 String root = paths[0]; 83 String mountPoint = paths[1]; 84 if (root != null && cgroupPath != null) { 85 if (root.equals("/")) { 86 if (!cgroupPath.equals("/")) { 87 finalPath = mountPoint + cgroupPath; 88 } else { 89 finalPath = mountPoint; 90 } 91 } else { 92 if (root.equals(cgroupPath)) { 93 finalPath = mountPoint; 94 } else { 95 if (cgroupPath.startsWith(root)) { 96 if (cgroupPath.length() > root.length()) { 97 String cgroupSubstr = cgroupPath.substring(root.length()); 98 finalPath = mountPoint + cgroupSubstr; 99 } 100 } 101 } 102 } 103 } 104 subSystemPaths.put(subSystem, new String[]{finalPath, mountPoint}); 105 } 106 } 107 } 108 109 private static void createSubsystems(String[] line) { 110 if (line.length < 5) return; 111 Path p = Paths.get(line[4]); 112 String subsystemName = p.getFileName().toString(); 113 if (subsystemName != null) { 114 for (String subSystem : subsystemName.split(",")) { 115 if (allowedSubSystems.contains(subSystem)) { 116 subSystemPaths.put(subSystem, new String[]{line[3], line[4]}); 117 } 118 } 119 } 120 } 121 122 public void setup() { 123 Metrics metrics = Metrics.systemMetrics(); 124 // Initialize CPU usage metrics before we do any testing. 125 startSysVal = metrics.getCpuSystemUsage(); 126 startUserVal = metrics.getCpuUserUsage(); 127 startUsage = metrics.getCpuUsage(); 128 startPerCpu = metrics.getPerCpuUsage(); 129 130 try { 131 Stream<String> lines = Files.lines(Paths.get("/proc/self/mountinfo")); 132 lines.filter(line -> line.contains(" - cgroup cgroup ")) 133 .map(line -> line.split(" ")) 134 .forEach(MetricsTesterCgroupV1::createSubsystems); 135 lines.close(); 136 137 lines = Files.lines(Paths.get("/proc/self/cgroup")); 138 lines.map(line -> line.split(":")) 139 .filter(line -> (line.length >= 3)) 140 .forEach(MetricsTesterCgroupV1::setPath); 141 lines.close(); 142 } catch (IOException e) { 143 } 144 } 145 146 private static String getFileContents(Controller subSystem, String fileName) { 147 String fname = subSystemPaths.get(subSystem.value())[0] + File.separator + fileName; 148 try { 149 return new Scanner(new File(fname)).useDelimiter("\\Z").next(); 150 } catch (FileNotFoundException e) { 151 System.err.println("Unable to open : " + fname); 152 return ""; 153 } 154 } 155 156 private static long getLongValueFromFile(Controller subSystem, String fileName) { 157 String data = getFileContents(subSystem, fileName); 158 return data.isEmpty() ? 0L : convertStringToLong(data); 159 } 160 161 private static long convertStringToLong(String strval) { 162 return CgroupMetricsTester.convertStringToLong(strval, Long.MAX_VALUE); 163 } 164 165 private static long getLongValueFromFile(Controller subSystem, String metric, String subMetric) { 166 String stats = getFileContents(subSystem, metric); 167 String[] tokens = stats.split("[\\r\\n]+"); 168 for (int i = 0; i < tokens.length; i++) { 169 if (tokens[i].startsWith(subMetric)) { 170 String strval = tokens[i].split("\\s+")[1]; 171 return convertStringToLong(strval); 172 } 173 } 174 return 0L; 175 } 176 177 private static double getDoubleValueFromFile(Controller subSystem, String fileName) { 178 String data = getFileContents(subSystem, fileName); 179 return data.isEmpty() ? 0.0 : Double.parseDouble(data); 180 } 181 182 private static void fail(Controller system, String metric, long oldVal, long testVal) { 183 CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); 184 } 185 186 private static void fail(Controller system, String metric, String oldVal, String testVal) { 187 CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); 188 } 189 190 private static void fail(Controller system, String metric, double oldVal, double testVal) { 191 CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); 192 } 193 194 private static void fail(Controller system, String metric, boolean oldVal, boolean testVal) { 195 CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); 196 } 197 198 private static void warn(Controller system, String metric, long oldVal, long testVal) { 199 CgroupMetricsTester.warn(system.value, metric, oldVal, testVal); 200 } 201 202 public void testMemorySubsystem() { 203 Metrics metrics = Metrics.systemMetrics(); 204 205 // User Memory 206 long oldVal = metrics.getMemoryFailCount(); 207 long newVal = getLongValueFromFile(Controller.MEMORY, "memory.failcnt"); 208 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 209 fail(Controller.MEMORY, "memory.failcnt", oldVal, newVal); 210 } 211 212 oldVal = metrics.getMemoryLimit(); 213 newVal = getLongValueFromFile(Controller.MEMORY, "memory.limit_in_bytes"); 214 newVal = newVal > unlimited_minimum ? -1L : newVal; 215 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 216 fail(Controller.MEMORY, "memory.limit_in_bytes", oldVal, newVal); 217 } 218 219 oldVal = metrics.getMemoryMaxUsage(); 220 newVal = getLongValueFromFile(Controller.MEMORY, "memory.max_usage_in_bytes"); 221 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 222 fail(Controller.MEMORY, "memory.max_usage_in_bytes", oldVal, newVal); 223 } 224 225 oldVal = metrics.getMemoryUsage(); 226 newVal = getLongValueFromFile(Controller.MEMORY, "memory.usage_in_bytes"); 227 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 228 fail(Controller.MEMORY, "memory.usage_in_bytes", oldVal, newVal); 229 } 230 231 // Kernel memory 232 oldVal = metrics.getKernelMemoryFailCount(); 233 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.failcnt"); 234 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 235 fail(Controller.MEMORY, "memory.kmem.failcnt", oldVal, newVal); 236 } 237 238 oldVal = metrics.getKernelMemoryLimit(); 239 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.limit_in_bytes"); 240 newVal = newVal > unlimited_minimum ? -1L : newVal; 241 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 242 fail(Controller.MEMORY, "memory.kmem.limit_in_bytes", oldVal, newVal); 243 } 244 245 oldVal = metrics.getKernelMemoryMaxUsage(); 246 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.max_usage_in_bytes"); 247 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 248 fail(Controller.MEMORY, "memory.kmem.max_usage_in_bytes", oldVal, newVal); 249 } 250 251 oldVal = metrics.getKernelMemoryUsage(); 252 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.usage_in_bytes"); 253 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 254 fail(Controller.MEMORY, "memory.kmem.usage_in_bytes", oldVal, newVal); 255 } 256 257 //TCP Memory 258 oldVal = metrics.getTcpMemoryFailCount(); 259 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.failcnt"); 260 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 261 fail(Controller.MEMORY, "memory.kmem.tcp.failcnt", oldVal, newVal); 262 } 263 264 oldVal = metrics.getTcpMemoryLimit(); 265 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes"); 266 newVal = newVal > unlimited_minimum ? -1L : newVal; 267 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 268 fail(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes", oldVal, newVal); 269 } 270 271 oldVal = metrics.getTcpMemoryMaxUsage(); 272 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.max_usage_in_bytes"); 273 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 274 fail(Controller.MEMORY, "memory.kmem.tcp.max_usage_in_bytes", oldVal, newVal); 275 } 276 277 oldVal = metrics.getTcpMemoryUsage(); 278 newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.usage_in_bytes"); 279 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 280 fail(Controller.MEMORY, "memory.kmem.tcp.usage_in_bytes", oldVal, newVal); 281 } 282 283 // Memory and Swap 284 oldVal = metrics.getMemoryAndSwapFailCount(); 285 newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.failcnt"); 286 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 287 fail(Controller.MEMORY, "memory.memsw.failcnt", oldVal, newVal); 288 } 289 290 oldVal = metrics.getMemoryAndSwapLimit(); 291 newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.limit_in_bytes"); 292 newVal = newVal > unlimited_minimum ? -1L : newVal; 293 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 294 fail(Controller.MEMORY, "memory.memsw.limit_in_bytes", oldVal, newVal); 295 } 296 297 oldVal = metrics.getMemoryAndSwapMaxUsage(); 298 newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.max_usage_in_bytes"); 299 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 300 fail(Controller.MEMORY, "memory.memsw.max_usage_in_bytes", oldVal, newVal); 301 } 302 303 oldVal = metrics.getMemoryAndSwapUsage(); 304 newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.usage_in_bytes"); 305 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 306 fail(Controller.MEMORY, "memory.memsw.usage_in_bytes", oldVal, newVal); 307 } 308 309 oldVal = metrics.getMemorySoftLimit(); 310 newVal = getLongValueFromFile(Controller.MEMORY, "memory.soft_limit_in_bytes"); 311 newVal = newVal > unlimited_minimum ? -1L : newVal; 312 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 313 fail(Controller.MEMORY, "memory.soft_limit_in_bytes", oldVal, newVal); 314 } 315 316 boolean oomKillEnabled = metrics.isMemoryOOMKillEnabled(); 317 boolean newOomKillEnabled = getLongValueFromFile(Controller.MEMORY, 318 "memory.oom_control", "oom_kill_disable") == 0L ? true : false; 319 if (oomKillEnabled != newOomKillEnabled) { 320 throw new RuntimeException("Test failed for - " + Controller.MEMORY.value + ":" 321 + "memory.oom_control:oom_kill_disable" + ", expected [" 322 + oomKillEnabled + "], got [" + newOomKillEnabled + "]"); 323 } 324 } 325 326 public void testCpuAccounting() { 327 Metrics metrics = Metrics.systemMetrics(); 328 long oldVal = metrics.getCpuUsage(); 329 long newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.usage"); 330 331 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 332 warn(Controller.CPUACCT, "cpuacct.usage", oldVal, newVal); 333 } 334 335 Long[] newVals = Stream.of(getFileContents(Controller.CPUACCT, "cpuacct.usage_percpu") 336 .split("\\s+")) 337 .map(Long::parseLong) 338 .toArray(Long[]::new); 339 Long[] oldVals = LongStream.of(metrics.getPerCpuUsage()).boxed().toArray(Long[]::new); 340 for (int i = 0; i < oldVals.length; i++) { 341 if (!CgroupMetricsTester.compareWithErrorMargin(oldVals[i], newVals[i])) { 342 warn(Controller.CPUACCT, "cpuacct.usage_percpu", oldVals[i], newVals[i]); 343 } 344 } 345 346 oldVal = metrics.getCpuUserUsage(); 347 newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.stat", "user"); 348 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 349 warn(Controller.CPUACCT, "cpuacct.usage - user", oldVal, newVal); 350 } 351 352 oldVal = metrics.getCpuSystemUsage(); 353 newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.stat", "system"); 354 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 355 warn(Controller.CPUACCT, "cpuacct.usage - system", oldVal, newVal); 356 } 357 } 358 359 public void testCpuSchedulingMetrics() { 360 Metrics metrics = Metrics.systemMetrics(); 361 long oldVal = metrics.getCpuPeriod(); 362 long newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.cfs_period_us"); 363 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 364 fail(Controller.CPUACCT, "cpu.cfs_period_us", oldVal, newVal); 365 } 366 367 oldVal = metrics.getCpuQuota(); 368 newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.cfs_quota_us"); 369 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 370 fail(Controller.CPUACCT, "cpu.cfs_quota_us", oldVal, newVal); 371 } 372 373 oldVal = metrics.getCpuShares(); 374 newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.shares"); 375 if (newVal == 0 || newVal == 1024) newVal = -1; 376 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 377 fail(Controller.CPUACCT, "cpu.shares", oldVal, newVal); 378 } 379 380 oldVal = metrics.getCpuNumPeriods(); 381 newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "nr_periods"); 382 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 383 fail(Controller.CPUACCT, "cpu.stat - nr_periods", oldVal, newVal); 384 } 385 386 oldVal = metrics.getCpuNumThrottled(); 387 newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "nr_throttled"); 388 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 389 fail(Controller.CPUACCT, "cpu.stat - nr_throttled", oldVal, newVal); 390 } 391 392 oldVal = metrics.getCpuThrottledTime(); 393 newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "throttled_time"); 394 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 395 fail(Controller.CPUACCT, "cpu.stat - throttled_time", oldVal, newVal); 396 } 397 } 398 399 public void testCpuSets() { 400 Metrics metrics = Metrics.systemMetrics(); 401 Integer[] oldVal = Arrays.stream(metrics.getCpuSetCpus()).boxed().toArray(Integer[]::new); 402 Arrays.sort(oldVal); 403 404 String cpusstr = getFileContents(Controller.CPUSET, "cpuset.cpus"); 405 // Parse range string in the format 1,2-6,7 406 Integer[] newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); 407 Arrays.sort(newVal); 408 if (Arrays.compare(oldVal, newVal) != 0) { 409 fail(Controller.CPUSET, "cpuset.cpus", Arrays.toString(oldVal), 410 Arrays.toString(newVal)); 411 } 412 413 int [] cpuSets = metrics.getEffectiveCpuSetCpus(); 414 415 // Skip this test if this metric is not supported on this platform 416 if (cpuSets.length != 0) { 417 oldVal = Arrays.stream(cpuSets).boxed().toArray(Integer[]::new); 418 Arrays.sort(oldVal); 419 cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_cpus"); 420 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); 421 Arrays.sort(newVal); 422 if (Arrays.compare(oldVal, newVal) != 0) { 423 fail(Controller.CPUSET, "cpuset.effective_cpus", Arrays.toString(oldVal), 424 Arrays.toString(newVal)); 425 } 426 } 427 428 oldVal = Arrays.stream(metrics.getCpuSetMems()).boxed().toArray(Integer[]::new); 429 Arrays.sort(oldVal); 430 cpusstr = getFileContents(Controller.CPUSET, "cpuset.mems"); 431 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); 432 Arrays.sort(newVal); 433 if (Arrays.compare(oldVal, newVal) != 0) { 434 fail(Controller.CPUSET, "cpuset.mems", Arrays.toString(oldVal), 435 Arrays.toString(newVal)); 436 } 437 438 int [] cpuSetMems = metrics.getEffectiveCpuSetMems(); 439 440 // Skip this test if this metric is not supported on this platform 441 if (cpuSetMems.length != 0) { 442 oldVal = Arrays.stream(cpuSetMems).boxed().toArray(Integer[]::new); 443 Arrays.sort(oldVal); 444 cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_mems"); 445 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); 446 Arrays.sort(newVal); 447 if (Arrays.compare(oldVal, newVal) != 0) { 448 fail(Controller.CPUSET, "cpuset.effective_mems", Arrays.toString(oldVal), 449 Arrays.toString(newVal)); 450 } 451 } 452 453 double oldValue = metrics.getCpuSetMemoryPressure(); 454 double newValue = getDoubleValueFromFile(Controller.CPUSET, "cpuset.memory_pressure"); 455 if (!CgroupMetricsTester.compareWithErrorMargin(oldValue, newValue)) { 456 fail(Controller.CPUSET, "cpuset.memory_pressure", oldValue, newValue); 457 } 458 459 boolean oldV = metrics.isCpuSetMemoryPressureEnabled(); 460 boolean newV = getLongValueFromFile(Controller.CPUSET, 461 "cpuset.memory_pressure_enabled") == 1 ? true : false; 462 if (oldV != newV) { 463 fail(Controller.CPUSET, "cpuset.memory_pressure_enabled", oldV, newV); 464 } 465 } 466 467 private void testBlkIO() { 468 Metrics metrics = Metrics.systemMetrics(); 469 long oldVal = metrics.getBlkIOServiceCount(); 470 long newVal = getLongValueFromFile(Controller.BLKIO, 471 "blkio.throttle.io_service_bytes", "Total"); 472 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 473 fail(Controller.BLKIO, "blkio.throttle.io_service_bytes - Total", 474 oldVal, newVal); 475 } 476 477 oldVal = metrics.getBlkIOServiced(); 478 newVal = getLongValueFromFile(Controller.BLKIO, "blkio.throttle.io_serviced", "Total"); 479 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { 480 fail(Controller.BLKIO, "blkio.throttle.io_serviced - Total", oldVal, newVal); 481 } 482 } 483 484 public void testCpuConsumption() throws IOException, InterruptedException { 485 Metrics metrics = Metrics.systemMetrics(); 486 // make system call 487 long newSysVal = metrics.getCpuSystemUsage(); 488 long newUserVal = metrics.getCpuUserUsage(); 489 long newUsage = metrics.getCpuUsage(); 490 long[] newPerCpu = metrics.getPerCpuUsage(); 491 492 // system/user CPU usage counters may be slowly increasing. 493 // allow for equal values for a pass 494 if (newSysVal < startSysVal) { 495 fail(Controller.CPU, "getCpuSystemUsage", newSysVal, startSysVal); 496 } 497 498 // system/user CPU usage counters may be slowly increasing. 499 // allow for equal values for a pass 500 if (newUserVal < startUserVal) { 501 fail(Controller.CPU, "getCpuUserUsage", newUserVal, startUserVal); 502 } 503 504 if (newUsage <= startUsage) { 505 fail(Controller.CPU, "getCpuUsage", newUsage, startUsage); 506 } 507 508 boolean success = false; 509 for (int i = 0; i < startPerCpu.length; i++) { 510 if (newPerCpu[i] > startPerCpu[i]) { 511 success = true; 512 break; 513 } 514 } 515 516 if(!success) fail(Controller.CPU, "getPerCpuUsage", Arrays.toString(newPerCpu), 517 Arrays.toString(startPerCpu)); 518 } 519 520 public void testMemoryUsage() throws Exception { 521 Metrics metrics = Metrics.systemMetrics(); 522 long memoryMaxUsage = metrics.getMemoryMaxUsage(); 523 long memoryUsage = metrics.getMemoryUsage(); 524 long newMemoryMaxUsage = 0, newMemoryUsage = 0; 525 526 // allocate memory in a loop and check more than once for new values 527 // otherwise we might see seldom the effect of decreasing new memory values 528 // e.g. because the system could free up memory 529 byte[][] bytes = new byte[32][]; 530 for (int i = 0; i < 32; i++) { 531 bytes[i] = new byte[8*1024*1024]; 532 newMemoryUsage = metrics.getMemoryUsage(); 533 if (newMemoryUsage > memoryUsage) { 534 break; 535 } 536 } 537 newMemoryMaxUsage = metrics.getMemoryMaxUsage(); 538 539 if (newMemoryMaxUsage < memoryMaxUsage) { 540 fail(Controller.MEMORY, "getMemoryMaxUsage", memoryMaxUsage, 541 newMemoryMaxUsage); 542 } 543 544 if (newMemoryUsage < memoryUsage) { 545 fail(Controller.MEMORY, "getMemoryUsage", memoryUsage, newMemoryUsage); 546 } 547 } 548 549 @Override 550 public void testMisc() { 551 testBlkIO(); 552 } 553 }