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