jdk-24/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java
2023-09-22 08:12:51 +00:00

130 lines
6.0 KiB
Java

/*
* Copyright (C) 2022 THL A29 Limited, a Tencent company. 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import jdk.test.lib.containers.docker.Common;
import jdk.test.lib.containers.docker.DockerTestUtils;
import jdk.test.lib.containers.docker.DockerRunOptions;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.internal.platform.Metrics;
/*
* @test
* @key cgroups
* @requires os.family == "linux"
* @modules java.base/jdk.internal.platform
* @library /test/lib
* @build jdk.test.whitebox.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar whitebox.jar jdk.test.whitebox.WhiteBox
* @run main TestMemoryWithCgroupV1
*/
public class TestMemoryWithCgroupV1 {
private static final String imageName = Common.imageName("memory");
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;
}
if ("cgroupv1".equals(metrics.getProvider())) {
if (!DockerTestUtils.canTestDocker()) {
return;
}
Common.prepareWhiteBox();
DockerTestUtils.buildJdkContainerImage(imageName);
try {
testMemoryLimitWithSwappiness("100M", "150M", "100.00M",
Integer.toString(((int) Math.pow(2, 20)) * 150),
Integer.toString(((int) Math.pow(2, 20)) * 100));
testOSBeanSwappinessMemory("200m", "250m", "0", "0");
} finally {
DockerTestUtils.removeDockerImage(imageName);
}
} else {
System.out.println("Memory swappiness not supported with cgroups v2. Test skipped.");
}
System.out.println("TEST PASSED!!!");
}
private static void testMemoryLimitWithSwappiness(String dockerMemLimit, String dockerSwapMemLimit,
String expectedLimit, String expectedReadLimit, String expectedResetLimit)
throws Exception {
Common.logNewTestCase("Test print_container_info()");
DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo").addJavaOpts("-XshowSettings:system");
opts.addDockerOpts("--cpus", "4"); // Avoid OOM kill on many-core systems
opts.addDockerOpts("--memory", dockerMemLimit, "--memory-swappiness", "0", "--memory-swap", dockerSwapMemLimit);
Common.addWhiteBoxOpts(opts);
OutputAnalyzer out = Common.run(opts);
// in case of warnings like : "Your kernel does not support swap limit
// capabilities or the cgroup is not mounted. Memory limited without swap."
// we only have 'Memory and Swap Limit is: -2' in the output
try {
if (out.getOutput().contains("Memory and Swap Limit is: -2")) {
System.out.println("System doesn't seem to allow swap, avoiding Memory and Swap Limit check");
} else {
out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit)
.shouldContain(
"Memory and Swap Limit has been reset to " + expectedResetLimit + " because swappiness is 0")
.shouldContain("Memory & Swap Limit: " + expectedLimit);
}
} catch (RuntimeException ex) {
System.out.println("Expected Memory and Swap Limit output missing.");
System.out.println("You may need to add 'cgroup_enable=memory swapaccount=1' to the Linux kernel boot parameters.");
throw ex;
}
}
private static void testOSBeanSwappinessMemory(String memoryAllocation, String swapAllocation,
String swappiness, String expectedSwap) throws Exception {
Common.logNewTestCase("Check OperatingSystemMXBean");
DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
.addDockerOpts("--cpus", "4") // Avoid OOM kill on many-core systems
.addDockerOpts(
"--memory", memoryAllocation,
"--memory-swappiness", swappiness,
"--memory-swap", swapAllocation)
// CheckOperatingSystemMXBean uses Metrics (jdk.internal.platform) for
// diagnostics
.addJavaOpts("--add-exports")
.addJavaOpts("java.base/jdk.internal.platform=ALL-UNNAMED");
OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts);
// in case of warnings like : "Your kernel does not support swap limit
// capabilities or the cgroup is not mounted. Memory limited without swap."
// the getTotalSwapSpaceSize and getFreeSwapSpaceSize return the system
// values as the container setup isn't supported in that case.
try {
out.shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap);
} catch (RuntimeException ex) {
out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: [0-9]+");
}
}
}