Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/test/runtime/containers/docker/TestCPUAwareness.java
32285 views
1
/*
2
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
25
/*
26
* @test
27
* @summary Test JVM's CPU resource awareness when running inside docker container
28
* @library /testlibrary /testlibrary/whitebox
29
* @build sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean
30
* @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
31
* @run driver TestCPUAwareness
32
*/
33
34
import java.util.List;
35
import com.oracle.java.testlibrary.Common;
36
import com.oracle.java.testlibrary.DockerTestUtils;
37
import com.oracle.java.testlibrary.DockerRunOptions;
38
39
public class TestCPUAwareness {
40
private static final String imageName = Common.imageName("cpu");
41
private static final int availableCPUs = Runtime.getRuntime().availableProcessors();
42
43
public static void main(String[] args) throws Exception {
44
if (!DockerTestUtils.canTestDocker()) {
45
return;
46
}
47
48
System.out.println("Test Environment: detected availableCPUs = " + availableCPUs);
49
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
50
51
try {
52
// cpuset, period, shares, expected Active Processor Count
53
testComboWithCpuSets();
54
55
// cpu shares - it should be safe to use CPU shares exceeding available CPUs
56
testCpuShares(256, 1);
57
testCpuShares(2048, 2);
58
testCpuShares(4096, 4);
59
60
// leave one CPU for system and tools, otherwise this test may be unstable
61
int maxNrOfAvailableCpus = availableCPUs - 1;
62
for (int i=1; i < maxNrOfAvailableCpus; i = i * 2) {
63
testCpus(i, i);
64
}
65
66
// If ActiveProcessorCount is set, the VM should use it, regardless of other
67
// container settings, host settings or available CPUs on the host.
68
testActiveProcessorCount(1, 1);
69
testActiveProcessorCount(2, 2);
70
71
// cpu quota and period
72
testCpuQuotaAndPeriod(50*1000, 100*1000);
73
testCpuQuotaAndPeriod(100*1000, 100*1000);
74
testCpuQuotaAndPeriod(150*1000, 100*1000);
75
testCpuQuotaAndPeriod(400*1000, 100*1000);
76
77
testOperatingSystemMXBeanAwareness("0.5", "1");
78
testOperatingSystemMXBeanAwareness("1.0", "1");
79
if (availableCPUs > 2) {
80
testOperatingSystemMXBeanAwareness("1.2", "2");
81
testOperatingSystemMXBeanAwareness("1.8", "2");
82
testOperatingSystemMXBeanAwareness("2.0", "2");
83
}
84
85
} finally {
86
DockerTestUtils.removeDockerImage(imageName);
87
}
88
}
89
90
91
private static void testComboWithCpuSets() throws Exception {
92
String cpuSetStr = CPUSetsReader.readFromProcStatus("Cpus_allowed_list");
93
System.out.println("cpuSetStr = " + cpuSetStr);
94
95
if (cpuSetStr == null) {
96
System.out.printf("The cpuset test cases are skipped");
97
} else {
98
List<Integer> cpuSet = CPUSetsReader.parseCpuSet(cpuSetStr);
99
100
// Test subset of cpuset with one element
101
if (cpuSet.size() >= 1) {
102
String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
103
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 1);
104
}
105
106
// Test subset of cpuset with two elements
107
if (cpuSet.size() >= 2) {
108
String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
109
testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
110
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
111
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
112
}
113
114
// Test subset of cpuset with three elements
115
if (cpuSet.size() >= 3) {
116
String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
117
testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
118
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, true, 2);
119
testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023, false, 1);
120
}
121
}
122
}
123
124
125
private static void testActiveProcessorCount(int valueToSet, int expectedValue) throws Exception {
126
Common.logNewTestCase("Test ActiveProcessorCount: valueToSet = " + valueToSet);
127
128
DockerRunOptions opts = Common.newOpts(imageName)
129
.addJavaOpts("-XX:ActiveProcessorCount=" + valueToSet, "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintActiveCpus");
130
Common.run(opts)
131
.shouldMatch("active processor count set by user.*" + expectedValue);
132
}
133
134
135
private static void testCpus(int valueToSet, int expectedTraceValue) throws Exception {
136
Common.logNewTestCase("test cpus: " + valueToSet);
137
DockerRunOptions opts = Common.newOpts(imageName)
138
.addDockerOpts("--cpu-period=" + 10000)
139
.addDockerOpts("--cpu-quota=" + valueToSet * 10000);
140
Common.run(opts)
141
.shouldMatch("active_processor_count.*" + expectedTraceValue);
142
}
143
144
145
// Expected active processor count can not exceed available CPU count
146
private static int adjustExpectedAPCForAvailableCPUs(int expectedAPC) {
147
if (expectedAPC > availableCPUs) {
148
expectedAPC = availableCPUs;
149
System.out.println("Adjusted expectedAPC = " + expectedAPC);
150
}
151
return expectedAPC;
152
}
153
154
155
private static void testCpuQuotaAndPeriod(int quota, int period)
156
throws Exception {
157
Common.logNewTestCase("test cpu quota and period: ");
158
System.out.println("quota = " + quota);
159
System.out.println("period = " + period);
160
161
int expectedAPC = (int) Math.ceil((float) quota / (float) period);
162
System.out.println("expectedAPC = " + expectedAPC);
163
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
164
165
DockerRunOptions opts = Common.newOpts(imageName)
166
.addDockerOpts("--cpu-period=" + period)
167
.addDockerOpts("--cpu-quota=" + quota);
168
169
Common.run(opts)
170
.shouldMatch("CPU Period is.*" + period)
171
.shouldMatch("CPU Quota is.*" + quota)
172
.shouldMatch("active_processor_count.*" + expectedAPC);
173
}
174
175
176
// Test correctess of automatically selected active processor cound
177
private static void testAPCCombo(String cpuset, int quota, int period, int shares,
178
boolean usePreferContainerQuotaForCPUCount,
179
int expectedAPC) throws Exception {
180
Common.logNewTestCase("test APC Combo");
181
System.out.println("cpuset = " + cpuset);
182
System.out.println("quota = " + quota);
183
System.out.println("period = " + period);
184
System.out.println("shares = " + period);
185
System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
186
System.out.println("expectedAPC = " + expectedAPC);
187
188
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
189
190
DockerRunOptions opts = Common.newOpts(imageName)
191
.addDockerOpts("--cpuset-cpus", "" + cpuset)
192
.addDockerOpts("--cpu-period=" + period)
193
.addDockerOpts("--cpu-quota=" + quota)
194
.addDockerOpts("--cpu-shares=" + shares);
195
196
if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");
197
198
Common.run(opts)
199
.shouldMatch("active_processor_count.*" + expectedAPC);
200
}
201
202
203
private static void testCpuShares(int shares, int expectedAPC) throws Exception {
204
Common.logNewTestCase("test cpu shares, shares = " + shares);
205
System.out.println("expectedAPC = " + expectedAPC);
206
207
expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
208
209
DockerRunOptions opts = Common.newOpts(imageName)
210
.addDockerOpts("--cpu-shares=" + shares);
211
Common.run(opts)
212
.shouldMatch("CPU Shares is.*" + shares)
213
.shouldMatch("active_processor_count.*" + expectedAPC);
214
}
215
216
private static void testOperatingSystemMXBeanAwareness(String cpuAllocation, String expectedCpus) throws Exception {
217
Common.logNewTestCase("Check OperatingSystemMXBean");
218
219
DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
220
.addDockerOpts(
221
"--cpus", cpuAllocation
222
);
223
224
DockerTestUtils.dockerRunJava(opts)
225
.shouldHaveExitValue(0)
226
.shouldContain("Checking OperatingSystemMXBean")
227
.shouldContain("Runtime.availableProcessors: " + expectedCpus)
228
.shouldContain("OperatingSystemMXBean.getAvailableProcessors: " + expectedCpus)
229
.shouldMatch("OperatingSystemMXBean\\.getSystemCpuLoad: [0-9]+\\.[0-9]+")
230
;
231
}
232
}
233
234