Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/test/runtime/containers/docker/TestCPUAwareness.java
32285 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/222324/*25* @test26* @summary Test JVM's CPU resource awareness when running inside docker container27* @library /testlibrary /testlibrary/whitebox28* @build sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean29* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission30* @run driver TestCPUAwareness31*/3233import java.util.List;34import com.oracle.java.testlibrary.Common;35import com.oracle.java.testlibrary.DockerTestUtils;36import com.oracle.java.testlibrary.DockerRunOptions;3738public class TestCPUAwareness {39private static final String imageName = Common.imageName("cpu");40private static final int availableCPUs = Runtime.getRuntime().availableProcessors();4142public static void main(String[] args) throws Exception {43if (!DockerTestUtils.canTestDocker()) {44return;45}4647System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);48DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");4950try {51// cpuset, period, shares, expected Active Processor Count52testComboWithCpuSets();5354// cpu shares - it should be safe to use CPU shares exceeding available CPUs55testCpuShares(256, 1);56testCpuShares(2048, 2);57testCpuShares(4096, 4);5859// leave one CPU for system and tools, otherwise this test may be unstable60int maxNrOfAvailableCpus = availableCPUs - 1;61for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {62testCpus(i, i);63}6465// If ActiveProcessorCount is set, the VM should use it, regardless of other66// container settings, host settings or available CPUs on the host.67testActiveProcessorCount(1, 1);68testActiveProcessorCount(2, 2);6970// cpu quota and period71testCpuQuotaAndPeriod(50*1000, 100*1000);72testCpuQuotaAndPeriod(100*1000, 100*1000);73testCpuQuotaAndPeriod(150*1000, 100*1000);74testCpuQuotaAndPeriod(400*1000, 100*1000);7576testOperatingSystemMXBeanAwareness("0.5", "1");77testOperatingSystemMXBeanAwareness("1.0", "1");78if (availableCPUs > 2) {79testOperatingSystemMXBeanAwareness("1.2", "2");80testOperatingSystemMXBeanAwareness("1.8", "2");81testOperatingSystemMXBeanAwareness("2.0", "2");82}8384} finally {85DockerTestUtils.removeDockerImage(imageName);86}87}888990private static void testComboWithCpuSets() throws Exception {91String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");92System.out.println("cpuSetStr = " + cpuSetStr);9394if (cpuSetStr == null) {95System.out.printf("The cpuset test cases are skipped");96} else {97List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);9899// Test subset of cpuset with one element100if (cpuSet.size() >= 1) {101String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);102testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);103}104105// Test subset of cpuset with two elements106if (cpuSet.size() >= 2) {107String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);108testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);109testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);110testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);111}112113// Test subset of cpuset with three elements114if (cpuSet.size() >= 3) {115String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);116testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);117testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);118testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);119}120}121}122123124private static void testActiveProcessorCount(int valueToSet, int expectedValue) throws Exception {125Common.logNewTestCase("Test ActiveProcessorCount: valueToSet = " + valueToSet);126127DockerRunOptions opts = Common.newOpts(imageName)128.addJavaOpts("-XX:ActiveProcessorCount=" + valueToSet, "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintActiveCpus");129Common.run(opts)130.shouldMatch("active processor count set by user.*" + expectedValue);131}132133134private static void testCpus(int valueToSet, int expectedTraceValue) throws Exception {135Common.logNewTestCase("test cpus: " + valueToSet);136DockerRunOptions opts = Common.newOpts(imageName)137.addDockerOpts("--cpu-period=" + 10000)138.addDockerOpts("--cpu-quota=" + valueToSet * 10000);139Common.run(opts)140.shouldMatch("active_processor_count.*" + expectedTraceValue);141}142143144// Expected active processor count can not exceed available CPU count145private static int adjustExpectedAPCForAvailableCPUs(int expectedAPC) {146if (expectedAPC > availableCPUs) {147expectedAPC = availableCPUs;148System.out.println("Adjusted expectedAPC = " + expectedAPC);149}150return expectedAPC;151}152153154private static void testCpuQuotaAndPeriod(int quota, int period)155throws Exception {156Common.logNewTestCase("test cpu quota and period: ");157System.out.println("quota = " + quota);158System.out.println("period = " + period);159160int expectedAPC = (int) Math.ceil((float) quota / (float) period);161System.out.println("expectedAPC = " + expectedAPC);162expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);163164DockerRunOptions opts = Common.newOpts(imageName)165.addDockerOpts("--cpu-period=" + period)166.addDockerOpts("--cpu-quota=" + quota);167168Common.run(opts)169.shouldMatch("CPU Period is.*" + period)170.shouldMatch("CPU Quota is.*" + quota)171.shouldMatch("active_processor_count.*" + expectedAPC);172}173174175// Test correctess of automatically selected active processor cound176private static void testAPCCombo(String cpuset, int quota, int period, int shares,177boolean usePreferContainerQuotaForCPUCount,178int expectedAPC) throws Exception {179Common.logNewTestCase("test APC Combo");180System.out.println("cpuset = " + cpuset);181System.out.println("quota = " + quota);182System.out.println("period = " + period);183System.out.println("shares = " + period);184System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);185System.out.println("expectedAPC = " + expectedAPC);186187expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);188189DockerRunOptions opts = Common.newOpts(imageName)190.addDockerOpts("--cpuset-cpus", "" + cpuset)191.addDockerOpts("--cpu-period=" + period)192.addDockerOpts("--cpu-quota=" + quota)193.addDockerOpts("--cpu-shares=" + shares);194195if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");196197Common.run(opts)198.shouldMatch("active_processor_count.*" + expectedAPC);199}200201202private static void testCpuShares(int shares, int expectedAPC) throws Exception {203Common.logNewTestCase("test cpu shares, shares = " + shares);204System.out.println("expectedAPC = " + expectedAPC);205206expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);207208DockerRunOptions opts = Common.newOpts(imageName)209.addDockerOpts("--cpu-shares=" + shares);210Common.run(opts)211.shouldMatch("CPU Shares is.*" + shares)212.shouldMatch("active_processor_count.*" + expectedAPC);213}214215private static void testOperatingSystemMXBeanAwareness(String cpuAllocation, String expectedCpus) throws Exception {216Common.logNewTestCase("Check OperatingSystemMXBean");217218DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")219.addDockerOpts(220"--cpus", cpuAllocation221);222223DockerTestUtils.dockerRunJava(opts)224.shouldHaveExitValue(0)225.shouldContain("Checking OperatingSystemMXBean")226.shouldContain("Runtime.availableProcessors: " + expectedCpus)227.shouldContain("OperatingSystemMXBean.getAvailableProcessors: " + expectedCpus)228.shouldMatch("OperatingSystemMXBean\\.getSystemCpuLoad: [0-9]+\\.[0-9]+")229;230}231}232233234