< 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 +1,7 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * 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,55 +24,53 @@
 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;
+import jdk.internal.platform.MetricsCgroupV1;
 
-public class MetricsTester {
+public class MetricsTesterCgroupV1 implements CgroupMetricsTester {
 
-    private static final double ERROR_MARGIN = 0.1;
     private static long unlimited_minimum = 0x7FFFFFFFFF000000L;
     long startSysVal;
     long startUserVal;
     long startUsage;
     long startPerCpu[];
 
-    enum SubSystem {
+    enum Controller {
         MEMORY("memory"),
         CPUSET("cpuset"),
         CPU("cpu"),
         CPUACCT("cpuacct"),
         BLKIO("blkio");
 
         private String value;
 
-        SubSystem(String value) {
+        Controller(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());
+            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,60 +125,50 @@
         // 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(MetricsTester::createSubsystems);
+                    .forEach(MetricsTesterCgroupV1::createSubsystems);
             lines.close();
 
             lines = Files.lines(Paths.get("/proc/self/cgroup"));
             lines.map(line -> line.split(":"))
                     .filter(line -> (line.length >= 3))
-                    .forEach(MetricsTester::setPath);
+                    .forEach(MetricsTesterCgroupV1::setPath);
             lines.close();
         } catch (IOException e) {
         }
     }
 
-    private static String getFileContents(SubSystem subSystem, String fileName) {
+    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 "";
+            return null;
         }
     }
 
-    private static long getLongValueFromFile(SubSystem subSystem, String fileName) {
+    private static long getLongValueFromFile(Controller subSystem, String fileName) {
         String data = getFileContents(subSystem, fileName);
-        return data.isEmpty() ? 0L : convertStringToLong(data);
+        return (data == null || 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;
+        return CgroupMetricsTester.convertStringToLong(strval, Long.MAX_VALUE);
     }
 
-    private static long getLongValueFromFile(SubSystem subSystem, String metric, String subMetric) {
+    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,400 +176,364 @@
             }
         }
         return 0L;
     }
 
-    private static double getDoubleValueFromFile(SubSystem subSystem, String fileName) {
+    private static double getDoubleValueFromFile(Controller 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(Controller system, String metric, long oldVal, long testVal) {
+        CgroupMetricsTester.fail(system.value, metric, oldVal, testVal);
     }
 
-    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(Controller system, String metric, String oldVal, String testVal) {
+        CgroupMetricsTester.fail(system.value, metric, oldVal, 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(Controller system, String metric, double oldVal, double testVal) {
+        CgroupMetricsTester.fail(system.value, metric, oldVal, 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(Controller system, String metric, boolean oldVal, boolean testVal) {
+        CgroupMetricsTester.fail(system.value, metric, oldVal, 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 + "]");
+    private static void warn(Controller system, String metric, long oldVal, long testVal) {
+        CgroupMetricsTester.warn(system.value, metric, oldVal, testVal);
     }
 
     public void testMemorySubsystem() {
-        Metrics metrics = Metrics.systemMetrics();
+        MetricsCgroupV1 metrics = (MetricsCgroupV1)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);
+        long newVal = getLongValueFromFile(Controller.MEMORY, "memory.failcnt");
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.MEMORY, "memory.failcnt", oldVal, newVal);
         }
 
         oldVal = metrics.getMemoryLimit();
-        newVal = getLongValueFromFile(SubSystem.MEMORY, "memory.limit_in_bytes");
+        newVal = getLongValueFromFile(Controller.MEMORY, "memory.limit_in_bytes");
         newVal = newVal > unlimited_minimum ? -1L : newVal;
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.limit_in_bytes", oldVal, newVal);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.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);
+        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(SubSystem.MEMORY, "memory.usage_in_bytes");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.usage_in_bytes", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.kmem.failcnt");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.kmem.failcnt", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.kmem.limit_in_bytes");
+        newVal = getLongValueFromFile(Controller.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);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.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);
+        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(SubSystem.MEMORY, "memory.kmem.usage_in_bytes");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.kmem.usage_in_bytes", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.kmem.tcp.failcnt");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.kmem.tcp.failcnt", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.kmem.tcp.limit_in_bytes");
+        newVal = getLongValueFromFile(Controller.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);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.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);
+        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(SubSystem.MEMORY, "memory.kmem.tcp.usage_in_bytes");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.kmem.tcp.usage_in_bytes", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.memsw.failcnt");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.memsw.failcnt", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.memsw.limit_in_bytes");
+        newVal = getLongValueFromFile(Controller.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);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.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);
+        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(SubSystem.MEMORY, "memory.memsw.usage_in_bytes");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.MEMORY, "memory.memsw.usage_in_bytes", oldVal, newVal);
+        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(SubSystem.MEMORY, "memory.soft_limit_in_bytes");
+        newVal = getLongValueFromFile(Controller.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);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.MEMORY, "memory.soft_limit_in_bytes", oldVal, newVal);
         }
 
         boolean oomKillEnabled = metrics.isMemoryOOMKillEnabled();
-        boolean newOomKillEnabled = getLongValueFromFile(SubSystem.MEMORY,
+        boolean newOomKillEnabled = getLongValueFromFile(Controller.MEMORY,
                 "memory.oom_control", "oom_kill_disable") == 0L ? true : false;
         if (oomKillEnabled != newOomKillEnabled) {
-            throw new RuntimeException("Test failed for - " + SubSystem.MEMORY.value + ":"
+            throw new RuntimeException("Test failed for - " + Controller.MEMORY.value + ":"
                     + "memory.oom_control:oom_kill_disable" + ", expected ["
                     + oomKillEnabled + "], got [" + newOomKillEnabled + "]");
         }
     }
 
     public void testCpuAccounting() {
-        Metrics metrics = Metrics.systemMetrics();
+        MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics();
         long oldVal = metrics.getCpuUsage();
-        long newVal = getLongValueFromFile(SubSystem.CPUACCT, "cpuacct.usage");
+        long newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.usage");
 
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            warn(SubSystem.CPUACCT, "cpuacct.usage", oldVal, newVal);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            warn(Controller.CPUACCT, "cpuacct.usage", oldVal, newVal);
         }
 
-        Long[] newVals = Stream.of(getFileContents(SubSystem.CPUACCT, "cpuacct.usage_percpu")
+        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[] oldVals = LongStream.of(metrics.getPerCpuUsage()).boxed().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 (!compareWithErrorMargin(oldVals[i], newVals[i])) {
-                warn(SubSystem.CPUACCT, "cpuacct.usage_percpu", oldVals[i], newVals[i]);
+            if (!CgroupMetricsTester.compareWithErrorMargin(oldVals[i], newVals[i])) {
+                warn(Controller.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);
+        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(SubSystem.CPUACCT, "cpuacct.stat", "system");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            warn(SubSystem.CPUACCT, "cpuacct.usage - system", oldVal, newVal);
+        newVal = getLongValueFromFile(Controller.CPUACCT, "cpuacct.stat", "system");
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            warn(Controller.CPUACCT, "cpuacct.usage - system", oldVal, newVal);
         }
     }
 
     public void testCpuSchedulingMetrics() {
-        Metrics metrics = Metrics.systemMetrics();
+        MetricsCgroupV1 metrics = (MetricsCgroupV1)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);
+        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(SubSystem.CPUACCT, "cpu.cfs_quota_us");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.CPUACCT, "cpu.cfs_quota_us", oldVal, newVal);
+        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(SubSystem.CPUACCT, "cpu.shares");
+        newVal = getLongValueFromFile(Controller.CPUACCT, "cpu.shares");
         if (newVal == 0 || newVal == 1024) newVal = -1;
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.CPUACCT, "cpu.shares", oldVal, newVal);
+        if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
+            fail(Controller.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);
+        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(SubSystem.CPUACCT, "cpu.stat", "nr_throttled");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.CPUACCT, "cpu.stat - nr_throttled", oldVal, newVal);
+        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(SubSystem.CPUACCT, "cpu.stat", "throttled_time");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.CPUACCT, "cpu.stat - throttled_time", oldVal, newVal);
+        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() {
-        Metrics metrics = Metrics.systemMetrics();
+        MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics();
         Integer[] oldVal = Arrays.stream(metrics.getCpuSetCpus()).boxed().toArray(Integer[]::new);
         Arrays.sort(oldVal);
 
-        String cpusstr = getFileContents(SubSystem.CPUSET, "cpuset.cpus");
+        String cpusstr = getFileContents(Controller.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);
+        Integer[] newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
         Arrays.sort(newVal);
         if (Arrays.compare(oldVal, newVal) != 0) {
-            fail(SubSystem.CPUSET, "cpuset.cpus", Arrays.toString(oldVal),
+            fail(Controller.CPUSET, "cpuset.cpus", Arrays.toString(oldVal),
                 Arrays.toString(newVal));
         }
 
         int [] cpuSets = metrics.getEffectiveCpuSetCpus();
 
-        // Skip this test if this metric is supported on this platform
+        // 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(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);
+            cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_cpus");
+            newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
             Arrays.sort(newVal);
             if (Arrays.compare(oldVal, newVal) != 0) {
-                fail(SubSystem.CPUSET, "cpuset.effective_cpus", Arrays.toString(oldVal),
+                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(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);
+        cpusstr = getFileContents(Controller.CPUSET, "cpuset.mems");
+        newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
         Arrays.sort(newVal);
         if (Arrays.compare(oldVal, newVal) != 0) {
-            fail(SubSystem.CPUSET, "cpuset.mems", Arrays.toString(oldVal),
+            fail(Controller.CPUSET, "cpuset.mems", Arrays.toString(oldVal),
                     Arrays.toString(newVal));
         }
 
         int [] cpuSetMems = metrics.getEffectiveCpuSetMems();
 
-        // Skip this test if this metric is supported on this platform
+        // 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(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);
+            cpusstr = getFileContents(Controller.CPUSET, "cpuset.effective_mems");
+            newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
             Arrays.sort(newVal);
             if (Arrays.compare(oldVal, newVal) != 0) {
-                fail(SubSystem.CPUSET, "cpuset.effective_mems", Arrays.toString(oldVal),
+                fail(Controller.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);
+        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(SubSystem.CPUSET,
+        boolean newV = getLongValueFromFile(Controller.CPUSET,
                 "cpuset.memory_pressure_enabled") == 1 ? true : false;
         if (oldV != newV) {
-            fail(SubSystem.CPUSET, "cpuset.memory_pressure_enabled", oldV, newV);
+            fail(Controller.CPUSET, "cpuset.memory_pressure_enabled", oldV, newV);
         }
     }
 
-    public void testBlkIO() {
-        Metrics metrics = Metrics.systemMetrics();
+    private void testBlkIO() {
+        MetricsCgroupV1 metrics = (MetricsCgroupV1)Metrics.systemMetrics();
             long oldVal = metrics.getBlkIOServiceCount();
-        long newVal = getLongValueFromFile(SubSystem.BLKIO,
+        long newVal = getLongValueFromFile(Controller.BLKIO,
                 "blkio.throttle.io_service_bytes", "Total");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.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(SubSystem.BLKIO, "blkio.throttle.io_serviced", "Total");
-        if (!compareWithErrorMargin(oldVal, newVal)) {
-            fail(SubSystem.BLKIO, "blkio.throttle.io_serviced - Total", oldVal, newVal);
+        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 {
-        Metrics metrics = Metrics.systemMetrics();
+        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(SubSystem.CPU, "getCpuSystemUsage", 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(SubSystem.CPU, "getCpuUserUsage", newUserVal, startUserVal);
+            fail(Controller.CPU, "getCpuUserUsage", newUserVal, startUserVal);
         }
 
         if (newUsage <= startUsage) {
-            fail(SubSystem.CPU, "getCpuUsage", 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(SubSystem.CPU, "getPerCpuUsage", Arrays.toString(newPerCpu),
+        if(!success) fail(Controller.CPU, "getPerCpuUsage", Arrays.toString(newPerCpu),
                 Arrays.toString(startPerCpu));
     }
 
     public void testMemoryUsage() throws Exception {
-        Metrics metrics = Metrics.systemMetrics();
+        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,34 +548,19 @@
             }
         }
         newMemoryMaxUsage = metrics.getMemoryMaxUsage();
 
         if (newMemoryMaxUsage < memoryMaxUsage) {
-            fail(SubSystem.MEMORY, "getMemoryMaxUsage", memoryMaxUsage,
+            fail(Controller.MEMORY, "getMemoryMaxUsage", memoryMaxUsage,
                     newMemoryMaxUsage);
         }
 
         if (newMemoryUsage < memoryUsage) {
-            fail(SubSystem.MEMORY, "getMemoryUsage", memoryUsage, newMemoryUsage);
+            fail(Controller.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!!!");
+    @Override
+    public void testMisc() {
+        testBlkIO();
     }
 }
< prev index next >