Path: blob/master/test/hotspot/jtreg/containers/docker/TestJFREvents.java
64475 views
/*1* Copyright (c) 2019, 2020, 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* @key cgroups27* @summary Ensure that certain JFR events return correct results for resource values28* when run inside Docker container, such as available CPU and memory.29* Also make sure that PIDs are based on value provided by container,30* not by the host system.31* @requires (docker.support & os.maxMemory >= 2g)32* @library /test/lib33* @modules java.base/jdk.internal.misc34* java.management35* jdk.jartool/sun.tools.jar36* @build JfrReporter37* @run driver TestJFREvents38*/39import java.util.List;40import jdk.test.lib.containers.docker.Common;41import jdk.test.lib.containers.docker.DockerRunOptions;42import jdk.test.lib.containers.docker.DockerTestUtils;43import jdk.test.lib.Asserts;44import jdk.test.lib.process.OutputAnalyzer;45import jdk.test.lib.Utils;464748public class TestJFREvents {49private static final String imageName = Common.imageName("jfr-events");50private static final String TEST_ENV_VARIABLE = "UNIQUE_VARIABLE_ABC592903XYZ";51private static final String TEST_ENV_VALUE = "unique_value_abc592903xyz";52private static final int availableCPUs = Runtime.getRuntime().availableProcessors();5354public static void main(String[] args) throws Exception {55System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);56if (!DockerTestUtils.canTestDocker()) {57return;58}5960DockerTestUtils.buildJdkContainerImage(imageName);6162try {6364long MB = 1024*1024;65testMemory("200m", "" + 200*MB);66testMemory("500m", "" + 500*MB);67testMemory("1g", "" + 1024*MB);6869testProcessInfo();7071testEnvironmentVariables();7273containerInfoTestCase();74testCpuUsage();75testCpuThrottling();76testMemoryUsage();77testIOUsage();78} finally {79DockerTestUtils.removeDockerImage(imageName);80}81}8283private static void containerInfoTestCase() throws Exception {84// Leave one CPU for system and tools, otherwise this test may be unstable.85// Try the memory sizes that were verified by testMemory tests before.86int maxNrOfAvailableCpus = availableCPUs - 1;87for (int cpus = 1; cpus < maxNrOfAvailableCpus; cpus *= 2) {88for (int mem : new int[]{ 200, 500, 1024 }) {89testContainerInfo(cpus, mem);90}91}92}9394private static void testContainerInfo(int expectedCPUs, int expectedMemoryMB) throws Exception {95Common.logNewTestCase("ContainerInfo: --cpus = " + expectedCPUs + " --memory=" + expectedMemoryMB + "m");96String eventName = "jdk.ContainerConfiguration";97long expectedSlicePeriod = 100000; // default slice period98long expectedMemoryLimit = expectedMemoryMB * 1024 * 1024;99100String cpuCountFld = "effectiveCpuCount";101String cpuQuotaFld = "cpuQuota";102String cpuSlicePeriodFld = "cpuSlicePeriod";103String memoryLimitFld = "memoryLimit";104105DockerTestUtils.dockerRunJava(106commonDockerOpts()107.addDockerOpts("--cpus=" + expectedCPUs)108.addDockerOpts("--memory=" + expectedMemoryMB + "m")109.addClassOptions(eventName))110.shouldHaveExitValue(0)111.shouldContain(cpuCountFld + " = " + expectedCPUs)112.shouldContain(cpuSlicePeriodFld + " = " + expectedSlicePeriod)113.shouldContain(cpuQuotaFld + " = " + expectedCPUs * expectedSlicePeriod)114.shouldContain(memoryLimitFld + " = " + expectedMemoryLimit);115}116117private static void testCpuUsage() throws Exception {118Common.logNewTestCase("CPU Usage");119String eventName = "jdk.ContainerCPUUsage";120121String cpuTimeFld = "cpuTime";122String cpuUserTimeFld = "cpuUserTime";123String cpuSystemTimeFld = "cpuSystemTime";124125DockerTestUtils.dockerRunJava(126commonDockerOpts()127.addClassOptions(eventName, "period=endChunk"))128.shouldHaveExitValue(0)129.shouldNotContain(cpuTimeFld + " = " + 0)130.shouldNotContain(cpuUserTimeFld + " = " + 0)131.shouldNotContain(cpuSystemTimeFld + " = " + 0);132}133134private static void testMemoryUsage() throws Exception {135Common.logNewTestCase("Memory Usage");136String eventName = "jdk.ContainerMemoryUsage";137138String memoryFailCountFld = "memoryFailCount";139String memoryUsageFld = "memoryUsage";140String swapMemoryUsageFld = "swapMemoryUsage";141142DockerTestUtils.dockerRunJava(143commonDockerOpts()144.addClassOptions(eventName, "period=endChunk"))145.shouldHaveExitValue(0)146.shouldContain(memoryFailCountFld)147.shouldContain(memoryUsageFld)148.shouldContain(swapMemoryUsageFld);149}150151private static void testIOUsage() throws Exception {152Common.logNewTestCase("I/O Usage");153String eventName = "jdk.ContainerIOUsage";154155String serviceRequestsFld = "serviceRequests";156String dataTransferredFld = "dataTransferred";157158DockerTestUtils.dockerRunJava(159commonDockerOpts()160.addClassOptions(eventName, "period=endChunk"))161.shouldHaveExitValue(0)162.shouldContain(serviceRequestsFld)163.shouldContain(dataTransferredFld);164}165166private static void testCpuThrottling() throws Exception {167Common.logNewTestCase("CPU Throttling");168String eventName = "jdk.ContainerCPUThrottling";169170String cpuElapsedSlicesFld = "cpuElapsedSlices";171String cpuThrottledSlicesFld = "cpuThrottledSlices";172String cpuThrottledTimeFld = "cpuThrottledTime";173174DockerTestUtils.dockerRunJava(175commonDockerOpts()176.addClassOptions(eventName, "period=endChunk"))177.shouldHaveExitValue(0)178.shouldContain(cpuElapsedSlicesFld)179.shouldContain(cpuThrottledSlicesFld)180.shouldContain(cpuThrottledTimeFld);181}182183184private static void testMemory(String valueToSet, String expectedValue) throws Exception {185Common.logNewTestCase("Memory: --memory = " + valueToSet);186DockerTestUtils.dockerRunJava(187commonDockerOpts()188.addDockerOpts("--memory=" + valueToSet)189.addClassOptions("jdk.PhysicalMemory"))190.shouldHaveExitValue(0)191.shouldContain("totalSize = " + expectedValue);192}193194195private static void testProcessInfo() throws Exception {196Common.logNewTestCase("ProcessInfo");197DockerTestUtils.dockerRunJava(198commonDockerOpts()199.addClassOptions("jdk.SystemProcess"))200.shouldHaveExitValue(0)201.shouldContain("pid = 1");202}203204private static DockerRunOptions commonDockerOpts() {205return new DockerRunOptions(imageName, "/jdk/bin/java", "JfrReporter")206.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/")207.addJavaOpts("-cp", "/test-classes/");208}209210211private static void testEnvironmentVariables() throws Exception {212Common.logNewTestCase("EnvironmentVariables");213214List<String> cmd = DockerTestUtils.buildJavaCommand(215commonDockerOpts()216.addClassOptions("jdk.InitialEnvironmentVariable"));217218ProcessBuilder pb = new ProcessBuilder(cmd);219// Container has JAVA_HOME defined via the Dockerfile; make sure220// it is reported by JFR event.221// Environment variable set in host system should not be visible inside a container,222// and should not be reported by JFR.223pb.environment().put(TEST_ENV_VARIABLE, TEST_ENV_VALUE);224225System.out.println("[COMMAND]\n" + Utils.getCommandLine(pb));226OutputAnalyzer out = new OutputAnalyzer(pb.start());227System.out.println("[STDERR]\n" + out.getStderr());228System.out.println("[STDOUT]\n" + out.getStdout());229230out.shouldHaveExitValue(0)231.shouldContain("key = JAVA_HOME")232.shouldContain("value = /jdk")233.shouldNotContain(TEST_ENV_VARIABLE)234.shouldNotContain(TEST_ENV_VALUE);235}236}237238239