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