< prev index next >

test/lib/jdk/test/lib/containers/cgroup/MetricsTesterCgroupV1.java

Print this page
@  rev 57734 : Review feedback
|
o  rev 57733 : 8231111: Cgroups v2: Rework Metrics in java.base so as to recognize unified hierarchy
|  Reviewed-by: bobv, mchung
~
o  rev 56862 : 8231111: Cgroups v2: Rework Metrics in java.base so as to recognize unified hierarchy
|  Reviewed-by: bobv
~

*** 1,7 **** /* ! * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 24,78 **** package jdk.test.lib.containers.cgroup; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; - import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; - import java.util.HashSet; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.stream.Collectors; - import java.util.stream.IntStream; import java.util.stream.LongStream; import java.util.stream.Stream; import jdk.internal.platform.Metrics; ! public class MetricsTester { - private static final double ERROR_MARGIN = 0.1; private static long unlimited_minimum = 0x7FFFFFFFFF000000L; long startSysVal; long startUserVal; long startUsage; long startPerCpu[]; ! enum SubSystem { MEMORY("memory"), CPUSET("cpuset"), CPU("cpu"), CPUACCT("cpuacct"), BLKIO("blkio"); private String value; ! SubSystem(String value) { this.value = value; } public String value() { return value; } } private static final Set<String> allowedSubSystems = ! Stream.of(SubSystem.values()).map(SubSystem::value).collect(Collectors.toSet()); private static final Map<String, String[]> subSystemPaths = new HashMap<>(); private static void setPath(String[] line) { String cgroupPath = line[2]; --- 24,76 ---- package jdk.test.lib.containers.cgroup; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.LongStream; import java.util.stream.Stream; + import jdk.internal.platform.Metrics; + import jdk.internal.platform.MetricsCgroupV1; ! public class MetricsTesterCgroupV1 implements CgroupMetricsTester { private static long unlimited_minimum = 0x7FFFFFFFFF000000L; long startSysVal; long startUserVal; long startUsage; long startPerCpu[]; ! enum Controller { MEMORY("memory"), CPUSET("cpuset"), CPU("cpu"), CPUACCT("cpuacct"), BLKIO("blkio"); private String value; ! Controller(String value) { this.value = value; } public String value() { return value; } } private static final Set<String> allowedSubSystems = ! Stream.of(Controller.values()).map(Controller::value).collect(Collectors.toSet()); private static final Map<String, String[]> subSystemPaths = new HashMap<>(); private static void setPath(String[] line) { String cgroupPath = line[2];
*** 127,186 **** // Initialize CPU usage metrics before we do any testing. startSysVal = metrics.getCpuSystemUsage(); startUserVal = metrics.getCpuUserUsage(); startUsage = metrics.getCpuUsage(); startPerCpu = metrics.getPerCpuUsage(); try { Stream<String> lines = Files.lines(Paths.get("/proc/self/mountinfo")); lines.filter(line -> line.contains(" - cgroup cgroup ")) .map(line -> line.split(" ")) ! .forEach(MetricsTester::createSubsystems); lines.close(); lines = Files.lines(Paths.get("/proc/self/cgroup")); lines.map(line -> line.split(":")) .filter(line -> (line.length >= 3)) ! .forEach(MetricsTester::setPath); lines.close(); } catch (IOException e) { } } ! private static String getFileContents(SubSystem subSystem, String fileName) { String fname = subSystemPaths.get(subSystem.value())[0] + File.separator + fileName; try { return new Scanner(new File(fname)).useDelimiter("\\Z").next(); } catch (FileNotFoundException e) { System.err.println("Unable to open : " + fname); ! return ""; } } ! private static long getLongValueFromFile(SubSystem subSystem, String fileName) { String data = getFileContents(subSystem, fileName); ! return data.isEmpty() ? 0L : convertStringToLong(data); } private static long convertStringToLong(String strval) { ! long retval = 0; ! if (strval == null) return 0L; ! ! try { ! retval = Long.parseLong(strval); ! } catch (NumberFormatException e) { ! // For some properties (e.g. memory.limit_in_bytes) we may overflow the range of signed long. ! // In this case, return Long.MAX_VALUE ! BigInteger b = new BigInteger(strval); ! if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { ! return Long.MAX_VALUE; ! } ! } ! return retval; } ! private static long getLongValueFromFile(SubSystem subSystem, String metric, String subMetric) { String stats = getFileContents(subSystem, metric); String[] tokens = stats.split("[\\r\\n]+"); for (int i = 0; i < tokens.length; i++) { if (tokens[i].startsWith(subMetric)) { String strval = tokens[i].split("\\s+")[1]; --- 125,174 ---- // Initialize CPU usage metrics before we do any testing. startSysVal = metrics.getCpuSystemUsage(); startUserVal = metrics.getCpuUserUsage(); startUsage = metrics.getCpuUsage(); startPerCpu = metrics.getPerCpuUsage(); + if (startPerCpu == null) { + startPerCpu = new long[0]; + } try { Stream<String> lines = Files.lines(Paths.get("/proc/self/mountinfo")); lines.filter(line -> line.contains(" - cgroup cgroup ")) .map(line -> line.split(" ")) ! .forEach(MetricsTesterCgroupV1::createSubsystems); lines.close(); lines = Files.lines(Paths.get("/proc/self/cgroup")); lines.map(line -> line.split(":")) .filter(line -> (line.length >= 3)) ! .forEach(MetricsTesterCgroupV1::setPath); lines.close(); } catch (IOException e) { } } ! private static String getFileContents(Controller subSystem, String fileName) { String fname = subSystemPaths.get(subSystem.value())[0] + File.separator + fileName; try { return new Scanner(new File(fname)).useDelimiter("\\Z").next(); } catch (FileNotFoundException e) { System.err.println("Unable to open : " + fname); ! return null; } } ! private static long getLongValueFromFile(Controller subSystem, String fileName) { String data = getFileContents(subSystem, fileName); ! return (data == null || data.isEmpty()) ? 0L : convertStringToLong(data); } private static long convertStringToLong(String strval) { ! return CgroupMetricsTester.convertStringToLong(strval, Long.MAX_VALUE); } ! private static long getLongValueFromFile(Controller subSystem, String metric, String subMetric) { String stats = getFileContents(subSystem, metric); String[] tokens = stats.split("[\\r\\n]+"); for (int i = 0; i < tokens.length; i++) { if (tokens[i].startsWith(subMetric)) { String strval = tokens[i].split("\\s+")[1];
*** 188,587 **** } } return 0L; } ! private static double getDoubleValueFromFile(SubSystem subSystem, String fileName) { String data = getFileContents(subSystem, fileName); return data.isEmpty() ? 0.0 : Double.parseDouble(data); } ! private boolean compareWithErrorMargin(long oldVal, long newVal) { ! return Math.abs(oldVal - newVal) <= Math.abs(oldVal * ERROR_MARGIN); ! } ! ! private boolean compareWithErrorMargin(double oldVal, double newVal) { ! return Math.abs(oldVal - newVal) <= Math.abs(oldVal * ERROR_MARGIN); } ! private static void fail(SubSystem system, String metric, long oldVal, long testVal) { ! throw new RuntimeException("Test failed for - " + system.value + ":" ! + metric + ", expected [" + oldVal + "], got [" + testVal + "]"); } ! private static void fail(SubSystem system, String metric, String oldVal, String testVal) { ! throw new RuntimeException("Test failed for - " + system.value + ":" ! + metric + ", expected [" + oldVal + "], got [" + testVal + "]"); } ! private static void fail(SubSystem system, String metric, double oldVal, double testVal) { ! throw new RuntimeException("Test failed for - " + system.value + ":" ! + metric + ", expected [" + oldVal + "], got [" + testVal + "]"); } ! private static void fail(SubSystem system, String metric, boolean oldVal, boolean testVal) { ! throw new RuntimeException("Test failed for - " + system.value + ":" ! + metric + ", expected [" + oldVal + "], got [" + testVal + "]"); ! } ! ! private static void warn(SubSystem system, String metric, long oldVal, long testVal) { ! System.err.println("Warning - " + system.value + ":" + metric ! + ", expected [" + oldVal + "], got [" + testVal + "]"); } public void testMemorySubsystem() { ! Metrics metrics = Metrics.systemMetrics(); // User Memory long oldVal = metrics.getMemoryFailCount(); ! long newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.failcnt"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.failcnt", oldVal, newVal); } oldVal = metrics.getMemoryLimit(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryMaxUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.max_usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.usage_in_bytes", oldVal, newVal); } // Kernel memory oldVal = metrics.getKernelMemoryFailCount(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.failcnt"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.failcnt", oldVal, newVal); } oldVal = metrics.getKernelMemoryLimit(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getKernelMemoryMaxUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.max_usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getKernelMemoryUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.usage_in_bytes", oldVal, newVal); } //TCP Memory oldVal = metrics.getTcpMemoryFailCount(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.tcp.failcnt"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.tcp.failcnt", oldVal, newVal); } oldVal = metrics.getTcpMemoryLimit(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.tcp.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.tcp.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getTcpMemoryMaxUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.tcp.max_usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.tcp.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getTcpMemoryUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.kmem.tcp.usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.kmem.tcp.usage_in_bytes", oldVal, newVal); } // Memory and Swap oldVal = metrics.getMemoryAndSwapFailCount(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.memsw.failcnt"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.memsw.failcnt", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapLimit(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.memsw.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.memsw.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapMaxUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.memsw.max_usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.memsw.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapUsage(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.memsw.usage_in_bytes"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.memsw.usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemorySoftLimit(); ! newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.soft_limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.MEMORY, "memory.soft_limit_in_bytes", oldVal, newVal); } boolean oomKillEnabled = metrics.isMemoryOOMKillEnabled(); ! boolean newOomKillEnabled = getLongValueFromFile(SubSystem.MEMORY, "memory.oom_control", "oom_kill_disable") == 0L ? true : false; if (oomKillEnabled != newOomKillEnabled) { ! throw new RuntimeException("Test failed for - " + SubSystem.MEMORY.value + ":" + "memory.oom_control:oom_kill_disable" + ", expected [" + oomKillEnabled + "], got [" + newOomKillEnabled + "]"); } } public void testCpuAccounting() { ! Metrics metrics = Metrics.systemMetrics(); long oldVal = metrics.getCpuUsage(); ! long newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpuacct.usage"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! warn(SubSystem.CPUACCT, "cpuacct.usage", oldVal, newVal); } ! Long[] newVals = Stream.of(getFileContents(SubSystem.CPUACCT, "cpuacct.usage_percpu") .split("\\s+")) .map(Long::parseLong) .toArray(Long[]::new); ! Long[] oldVals = LongStream.of(metrics.getPerCpuUsage()).boxed().toArray(Long[]::new); for (int i = 0; i < oldVals.length; i++) { ! if (!compareWithErrorMargin(oldVals[i], newVals[i])) { ! warn(SubSystem.CPUACCT, "cpuacct.usage_percpu", oldVals[i], newVals[i]); } } oldVal = metrics.getCpuUserUsage(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpuacct.stat", "user"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! warn(SubSystem.CPUACCT, "cpuacct.usage - user", oldVal, newVal); } oldVal = metrics.getCpuSystemUsage(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpuacct.stat", "system"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! warn(SubSystem.CPUACCT, "cpuacct.usage - system", oldVal, newVal); } } public void testCpuSchedulingMetrics() { ! Metrics metrics = Metrics.systemMetrics(); long oldVal = metrics.getCpuPeriod(); ! long newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.cfs_period_us"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.cfs_period_us", oldVal, newVal); } oldVal = metrics.getCpuQuota(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.cfs_quota_us"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.cfs_quota_us", oldVal, newVal); } oldVal = metrics.getCpuShares(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.shares"); if (newVal == 0 || newVal == 1024) newVal = -1; ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.shares", oldVal, newVal); } oldVal = metrics.getCpuNumPeriods(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.stat", "nr_periods"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.stat - nr_periods", oldVal, newVal); } oldVal = metrics.getCpuNumThrottled(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.stat", "nr_throttled"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.stat - nr_throttled", oldVal, newVal); } oldVal = metrics.getCpuThrottledTime(); ! newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpu.stat", "throttled_time"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.CPUACCT, "cpu.stat - throttled_time", oldVal, newVal); } } public void testCpuSets() { ! Metrics metrics = Metrics.systemMetrics(); Integer[] oldVal = Arrays.stream(metrics.getCpuSetCpus()).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! String cpusstr = getFileContents(SubSystem.CPUSET, "cpuset.cpus"); // Parse range string in the format 1,2-6,7 ! Integer[] newVal = Stream.of(cpusstr.split(",")).flatMap(a -> { ! if (a.contains("-")) { ! String[] range = a.split("-"); ! return IntStream.rangeClosed(Integer.parseInt(range[0]), ! Integer.parseInt(range[1])).boxed(); ! } else { ! return Stream.of(Integer.parseInt(a)); ! } ! }).toArray(Integer[]::new); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(SubSystem.CPUSET, "cpuset.cpus", Arrays.toString(oldVal), Arrays.toString(newVal)); } int [] cpuSets = metrics.getEffectiveCpuSetCpus(); ! // Skip this test if this metric is supported on this platform if (cpuSets.length != 0) { oldVal = Arrays.stream(cpuSets).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(SubSystem.CPUSET, "cpuset.effective_cpus"); ! newVal = Stream.of(cpusstr.split(",")).flatMap(a -> { ! if (a.contains("-")) { ! String[] range = a.split("-"); ! return IntStream.rangeClosed(Integer.parseInt(range[0]), ! Integer.parseInt(range[1])).boxed(); ! } else { ! return Stream.of(Integer.parseInt(a)); ! } ! }).toArray(Integer[]::new); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(SubSystem.CPUSET, "cpuset.effective_cpus", Arrays.toString(oldVal), Arrays.toString(newVal)); } } oldVal = Arrays.stream(metrics.getCpuSetMems()).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(SubSystem.CPUSET, "cpuset.mems"); ! newVal = Stream.of(cpusstr.split(",")).flatMap(a -> { ! if (a.contains("-")) { ! String[] range = a.split("-"); ! return IntStream.rangeClosed(Integer.parseInt(range[0]), ! Integer.parseInt(range[1])).boxed(); ! } else { ! return Stream.of(Integer.parseInt(a)); ! } ! }).toArray(Integer[]::new); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(SubSystem.CPUSET, "cpuset.mems", Arrays.toString(oldVal), Arrays.toString(newVal)); } int [] cpuSetMems = metrics.getEffectiveCpuSetMems(); ! // Skip this test if this metric is supported on this platform if (cpuSetMems.length != 0) { oldVal = Arrays.stream(cpuSetMems).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(SubSystem.CPUSET, "cpuset.effective_mems"); ! newVal = Stream.of(cpusstr.split(",")).flatMap(a -> { ! if (a.contains("-")) { ! String[] range = a.split("-"); ! return IntStream.rangeClosed(Integer.parseInt(range[0]), ! Integer.parseInt(range[1])).boxed(); ! } else { ! return Stream.of(Integer.parseInt(a)); ! } ! }).toArray(Integer[]::new); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(SubSystem.CPUSET, "cpuset.effective_mems", Arrays.toString(oldVal), Arrays.toString(newVal)); } } double oldValue = metrics.getCpuSetMemoryPressure(); ! double newValue = getDoubleValueFromFile(SubSystem.CPUSET, "cpuset.memory_pressure"); ! if (!compareWithErrorMargin(oldValue, newValue)) { ! fail(SubSystem.CPUSET, "cpuset.memory_pressure", oldValue, newValue); } boolean oldV = metrics.isCpuSetMemoryPressureEnabled(); ! boolean newV = getLongValueFromFile(SubSystem.CPUSET, "cpuset.memory_pressure_enabled") == 1 ? true : false; if (oldV != newV) { ! fail(SubSystem.CPUSET, "cpuset.memory_pressure_enabled", oldV, newV); } } ! public void testBlkIO() { ! Metrics metrics = Metrics.systemMetrics(); long oldVal = metrics.getBlkIOServiceCount(); ! long newVal = getLongValueFromFile(SubSystem.BLKIO, "blkio.throttle.io_service_bytes", "Total"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.BLKIO, "blkio.throttle.io_service_bytes - Total", oldVal, newVal); } oldVal = metrics.getBlkIOServiced(); ! newVal = getLongValueFromFile(SubSystem.BLKIO, "blkio.throttle.io_serviced", "Total"); ! if (!compareWithErrorMargin(oldVal, newVal)) { ! fail(SubSystem.BLKIO, "blkio.throttle.io_serviced - Total", oldVal, newVal); } } public void testCpuConsumption() throws IOException, InterruptedException { ! Metrics metrics = Metrics.systemMetrics(); // make system call long newSysVal = metrics.getCpuSystemUsage(); long newUserVal = metrics.getCpuUserUsage(); long newUsage = metrics.getCpuUsage(); long[] newPerCpu = metrics.getPerCpuUsage(); // system/user CPU usage counters may be slowly increasing. // allow for equal values for a pass if (newSysVal < startSysVal) { ! fail(SubSystem.CPU, "getCpuSystemUsage", newSysVal, startSysVal); } // system/user CPU usage counters may be slowly increasing. // allow for equal values for a pass if (newUserVal < startUserVal) { ! fail(SubSystem.CPU, "getCpuUserUsage", newUserVal, startUserVal); } if (newUsage <= startUsage) { ! fail(SubSystem.CPU, "getCpuUsage", newUsage, startUsage); } boolean success = false; for (int i = 0; i < startPerCpu.length; i++) { if (newPerCpu[i] > startPerCpu[i]) { success = true; break; } } ! if(!success) fail(SubSystem.CPU, "getPerCpuUsage", Arrays.toString(newPerCpu), Arrays.toString(startPerCpu)); } public void testMemoryUsage() throws Exception { ! Metrics metrics = Metrics.systemMetrics(); long memoryMaxUsage = metrics.getMemoryMaxUsage(); long memoryUsage = metrics.getMemoryUsage(); long newMemoryMaxUsage = 0, newMemoryUsage = 0; // allocate memory in a loop and check more than once for new values --- 176,539 ---- } } return 0L; } ! private static double getDoubleValueFromFile(Controller subSystem, String fileName) { String data = getFileContents(subSystem, fileName); return data.isEmpty() ? 0.0 : Double.parseDouble(data); } ! private static void fail(Controller system, String metric, long oldVal, long testVal) { ! CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); } ! private static void fail(Controller system, String metric, String oldVal, String testVal) { ! CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); } ! private static void fail(Controller system, String metric, double oldVal, double testVal) { ! CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); } ! private static void fail(Controller system, String metric, boolean oldVal, boolean testVal) { ! CgroupMetricsTester.fail(system.value, metric, oldVal, testVal); } ! private static void warn(Controller system, String metric, long oldVal, long testVal) { ! CgroupMetricsTester.warn(system.value, metric, oldVal, testVal); } public void testMemorySubsystem() { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); // User Memory long oldVal = metrics.getMemoryFailCount(); ! long newVal = getLongValueFromFile(Controller.MEMORY, "memory.failcnt"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.failcnt", oldVal, newVal); } oldVal = metrics.getMemoryLimit(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryMaxUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.max_usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.usage_in_bytes", oldVal, newVal); } // Kernel memory oldVal = metrics.getKernelMemoryFailCount(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.failcnt"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.failcnt", oldVal, newVal); } oldVal = metrics.getKernelMemoryLimit(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getKernelMemoryMaxUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.max_usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getKernelMemoryUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.usage_in_bytes", oldVal, newVal); } //TCP Memory oldVal = metrics.getTcpMemoryFailCount(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.failcnt"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.tcp.failcnt", oldVal, newVal); } oldVal = metrics.getTcpMemoryLimit(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.tcp.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getTcpMemoryMaxUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.max_usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.tcp.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getTcpMemoryUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.kmem.tcp.usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.kmem.tcp.usage_in_bytes", oldVal, newVal); } // Memory and Swap oldVal = metrics.getMemoryAndSwapFailCount(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.failcnt"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.memsw.failcnt", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapLimit(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.memsw.limit_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapMaxUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.max_usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.memsw.max_usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemoryAndSwapUsage(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.memsw.usage_in_bytes"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.memsw.usage_in_bytes", oldVal, newVal); } oldVal = metrics.getMemorySoftLimit(); ! newVal = getLongValueFromFile(Controller.MEMORY, "memory.soft_limit_in_bytes"); newVal = newVal > unlimited_minimum ? -1L : newVal; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.MEMORY, "memory.soft_limit_in_bytes", oldVal, newVal); } boolean oomKillEnabled = metrics.isMemoryOOMKillEnabled(); ! boolean newOomKillEnabled = getLongValueFromFile(Controller.MEMORY, "memory.oom_control", "oom_kill_disable") == 0L ? true : false; if (oomKillEnabled != newOomKillEnabled) { ! throw new RuntimeException("Test failed for - " + Controller.MEMORY.value + ":" + "memory.oom_control:oom_kill_disable" + ", expected [" + oomKillEnabled + "], got [" + newOomKillEnabled + "]"); } } public void testCpuAccounting() { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); long oldVal = metrics.getCpuUsage(); ! long newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.usage"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! warn(Controller.CPUACCT, "cpuacct.usage", oldVal, newVal); } ! String newValsStr = getFileContents(Controller.CPUACCT, "cpuacct.usage_percpu"); ! Long[] newVals = new Long[0]; ! if (newValsStr != null) { ! newVals = Stream.of(newValsStr .split("\\s+")) .map(Long::parseLong) .toArray(Long[]::new); ! } ! long[] oldValsPrim = metrics.getPerCpuUsage(); ! Long[] oldVals = LongStream.of(oldValsPrim == null ? new long[0] : oldValsPrim) ! .boxed().toArray(Long[]::new); for (int i = 0; i < oldVals.length; i++) { ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVals[i], newVals[i])) { ! warn(Controller.CPUACCT, "cpuacct.usage_percpu", oldVals[i], newVals[i]); } } oldVal = metrics.getCpuUserUsage(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.stat", "user"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! warn(Controller.CPUACCT, "cpuacct.usage - user", oldVal, newVal); } oldVal = metrics.getCpuSystemUsage(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.stat", "system"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! warn(Controller.CPUACCT, "cpuacct.usage - system", oldVal, newVal); } } public void testCpuSchedulingMetrics() { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); long oldVal = metrics.getCpuPeriod(); ! long newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.cfs_period_us"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.cfs_period_us", oldVal, newVal); } oldVal = metrics.getCpuQuota(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.cfs_quota_us"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.cfs_quota_us", oldVal, newVal); } oldVal = metrics.getCpuShares(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.shares"); if (newVal == 0 || newVal == 1024) newVal = -1; ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.shares", oldVal, newVal); } oldVal = metrics.getCpuNumPeriods(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "nr_periods"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.stat - nr_periods", oldVal, newVal); } oldVal = metrics.getCpuNumThrottled(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "nr_throttled"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.stat - nr_throttled", oldVal, newVal); } oldVal = metrics.getCpuThrottledTime(); ! newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.stat", "throttled_time"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.CPUACCT, "cpu.stat - throttled_time", oldVal, newVal); } } public void testCpuSets() { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); Integer[] oldVal = Arrays.stream(metrics.getCpuSetCpus()).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! String cpusstr = getFileContents(Controller.CPUSET, "cpuset.cpus"); // Parse range string in the format 1,2-6,7 ! Integer[] newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(Controller.CPUSET, "cpuset.cpus", Arrays.toString(oldVal), Arrays.toString(newVal)); } int [] cpuSets = metrics.getEffectiveCpuSetCpus(); ! // Skip this test if this metric is not supported on this platform if (cpuSets.length != 0) { oldVal = Arrays.stream(cpuSets).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_cpus"); ! newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(Controller.CPUSET, "cpuset.effective_cpus", Arrays.toString(oldVal), Arrays.toString(newVal)); } } oldVal = Arrays.stream(metrics.getCpuSetMems()).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(Controller.CPUSET, "cpuset.mems"); ! newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(Controller.CPUSET, "cpuset.mems", Arrays.toString(oldVal), Arrays.toString(newVal)); } int [] cpuSetMems = metrics.getEffectiveCpuSetMems(); ! // Skip this test if this metric is not supported on this platform if (cpuSetMems.length != 0) { oldVal = Arrays.stream(cpuSetMems).boxed().toArray(Integer[]::new); Arrays.sort(oldVal); ! cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_mems"); ! newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr); Arrays.sort(newVal); if (Arrays.compare(oldVal, newVal) != 0) { ! fail(Controller.CPUSET, "cpuset.effective_mems", Arrays.toString(oldVal), Arrays.toString(newVal)); } } double oldValue = metrics.getCpuSetMemoryPressure(); ! double newValue = getDoubleValueFromFile(Controller.CPUSET, "cpuset.memory_pressure"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldValue, newValue)) { ! fail(Controller.CPUSET, "cpuset.memory_pressure", oldValue, newValue); } boolean oldV = metrics.isCpuSetMemoryPressureEnabled(); ! boolean newV = getLongValueFromFile(Controller.CPUSET, "cpuset.memory_pressure_enabled") == 1 ? true : false; if (oldV != newV) { ! fail(Controller.CPUSET, "cpuset.memory_pressure_enabled", oldV, newV); } } ! private void testBlkIO() { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); long oldVal = metrics.getBlkIOServiceCount(); ! long newVal = getLongValueFromFile(Controller.BLKIO, "blkio.throttle.io_service_bytes", "Total"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.BLKIO, "blkio.throttle.io_service_bytes - Total", oldVal, newVal); } oldVal = metrics.getBlkIOServiced(); ! newVal = getLongValueFromFile(Controller.BLKIO, "blkio.throttle.io_serviced", "Total"); ! if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) { ! fail(Controller.BLKIO, "blkio.throttle.io_serviced - Total", oldVal, newVal); } } public void testCpuConsumption() throws IOException, InterruptedException { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); // make system call long newSysVal = metrics.getCpuSystemUsage(); long newUserVal = metrics.getCpuUserUsage(); long newUsage = metrics.getCpuUsage(); long[] newPerCpu = metrics.getPerCpuUsage(); + if (newPerCpu == null) { + newPerCpu = new long[0]; + } // system/user CPU usage counters may be slowly increasing. // allow for equal values for a pass if (newSysVal < startSysVal) { ! fail(Controller.CPU, "getCpuSystemUsage", newSysVal, startSysVal); } // system/user CPU usage counters may be slowly increasing. // allow for equal values for a pass if (newUserVal < startUserVal) { ! fail(Controller.CPU, "getCpuUserUsage", newUserVal, startUserVal); } if (newUsage <= startUsage) { ! fail(Controller.CPU, "getCpuUsage", newUsage, startUsage); } boolean success = false; for (int i = 0; i < startPerCpu.length; i++) { if (newPerCpu[i] > startPerCpu[i]) { success = true; break; } } ! if(!success) fail(Controller.CPU, "getPerCpuUsage", Arrays.toString(newPerCpu), Arrays.toString(startPerCpu)); } public void testMemoryUsage() throws Exception { ! MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics(); long memoryMaxUsage = metrics.getMemoryMaxUsage(); long memoryUsage = metrics.getMemoryUsage(); long newMemoryMaxUsage = 0, newMemoryUsage = 0; // allocate memory in a loop and check more than once for new values
*** 596,629 **** } } newMemoryMaxUsage = metrics.getMemoryMaxUsage(); if (newMemoryMaxUsage < memoryMaxUsage) { ! fail(SubSystem.MEMORY, "getMemoryMaxUsage", memoryMaxUsage, newMemoryMaxUsage); } if (newMemoryUsage < memoryUsage) { ! fail(SubSystem.MEMORY, "getMemoryUsage", memoryUsage, newMemoryUsage); } } ! public static void main(String[] args) throws Exception { ! // If cgroups is not configured, report success ! Metrics metrics = Metrics.systemMetrics(); ! if (metrics == null) { ! System.out.println("TEST PASSED!!!"); ! return; ! } ! ! MetricsTester metricsTester = new MetricsTester(); ! metricsTester.setup(); ! metricsTester.testCpuAccounting(); ! metricsTester.testCpuSchedulingMetrics(); ! metricsTester.testCpuSets(); ! metricsTester.testMemorySubsystem(); ! metricsTester.testBlkIO(); ! metricsTester.testCpuConsumption(); ! metricsTester.testMemoryUsage(); ! System.out.println("TEST PASSED!!!"); } } --- 548,566 ---- } } newMemoryMaxUsage = metrics.getMemoryMaxUsage(); if (newMemoryMaxUsage < memoryMaxUsage) { ! fail(Controller.MEMORY, "getMemoryMaxUsage", memoryMaxUsage, newMemoryMaxUsage); } if (newMemoryUsage < memoryUsage) { ! fail(Controller.MEMORY, "getMemoryUsage", memoryUsage, newMemoryUsage); } } ! @Override ! public void testMisc() { ! testBlkIO(); } }
< prev index next >