1 /*
2 * Copyright (c) 2019, Red Hat Inc.
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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
132 }
133 }
134
135 private String getStringVal(String file) {
136 Path filePath = Paths.get(UNIFIED.getPath(), file);
137 try {
138 return Files.lines(filePath).collect(Collectors.joining());
139 } catch (IOException e) {
140 return null;
141 }
142 }
143
144 private void fail(String metric, long oldVal, long newVal) {
145 CgroupMetricsTester.fail(UnifiedController.NAME, metric, oldVal, newVal);
146 }
147
148 private void fail(String metric, String oldVal, String newVal) {
149 CgroupMetricsTester.fail(UnifiedController.NAME, metric, oldVal, newVal);
150 }
151
152 private void fail(String metric, String message) {
153 throw new RuntimeException(metric + ": " + message);
154 }
155
156 private void warn(String metric, long oldVal, long newVal) {
157 CgroupMetricsTester.warn(UnifiedController.NAME, metric, oldVal, newVal);
158 }
159
160 private void verifyNotSupported(long metricVal) {
161 Asserts.assertEquals(metricVal, NOT_SUPPORTED, "Expected metric to be not supported!");
162 }
163
164 private void verifyNotSupported(double metricVal) {
165 if (!CgroupMetricsTester.compareWithErrorMargin(NOT_SUPPORTED, metricVal)) {
166 throw new RuntimeException("Metric not supported, got: " + metricVal +
167 " expected: " + NOT_SUPPORTED);
168 }
169 }
170
171 private void verifyPerCpuNotSupported(long[] perCpuUsage) {
172 if (!Arrays.equals(perCpuUsage, new long[0])) {
173 throw new RuntimeException("perCpuUsage expected to be not supported");
174 };
175 }
176
177 private long getCpuShares(String file) {
178 long rawVal = getLongValueFromFile(file);
179 if (rawVal == 0 || rawVal == 100) {
180 return UNLIMITED;
181 }
182 int shares = (int)rawVal;
183 // CPU shares (OCI) value needs to get translated into
184 // a proper Cgroups v2 value. See:
185 // https://github.com/containers/crun/blob/master/crun.1.md#cpu-controller
186 //
187 // Use the inverse of (x == OCI value, y == cgroupsv2 value):
188 // ((262142 * y - 1)/9999) + 2 = x
189 //
190 int x = 262142 * shares - 1;
191 double frac = x/9999.0;
192 x = ((int)frac) + 2;
193 if ( x <= PER_CPU_SHARES ) {
194 return PER_CPU_SHARES; // mimic cgroups v1
195 }
196 int f = x/PER_CPU_SHARES;
197 int lower_multiple = f * PER_CPU_SHARES;
198 int upper_multiple = (f + 1) * PER_CPU_SHARES;
199 int distance_lower = Math.max(lower_multiple, x) - Math.min(lower_multiple, x);
200 int distance_upper = Math.max(upper_multiple, x) - Math.min(upper_multiple, x);
201 x = distance_lower <= distance_upper ? lower_multiple : upper_multiple;
202 return x;
203 }
204
205 private long getCpuMaxValueFromFile(String file) {
206 return getCpuValueFromFile(file, 0 /* $MAX index */);
207 }
208
209 private long getCpuPeriodValueFromFile(String file) {
210 return getCpuValueFromFile(file, 1 /* $PERIOD index */);
211 }
212
213 private long getCpuValueFromFile(String file, int index) {
214 String maxPeriod = getStringVal(file);
215 String[] tokens = maxPeriod.split("\\s+");
216 String val = tokens[index];
217 if (MAX.equals(val)) {
218 return UNLIMITED;
219 }
220 return convertStringToLong(val);
221 }
222
223 private long convertStringToLong(String val) {
224 return CgroupMetricsTester.convertStringToLong(val, UNLIMITED);
225 }
226
227 @Override
228 public void testMemorySubsystem() {
229 Metrics metrics = Metrics.systemMetrics();
230
231 long memoryMaxUsageMin;
232 // User Memory
233 long oldVal = metrics.getMemoryFailCount();
234 long newVal = getLongValueEntryFromFile("memory.events", "max");
235 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
236 fail("memory.events[max]", oldVal, newVal);
237 }
238
239 oldVal = metrics.getMemoryLimit();
240 newVal = getLongLimitValueFromFile("memory.max");
241 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
242 fail("memory.max", oldVal, newVal);
243 }
244
245 memoryMaxUsageMin = oldVal = metrics.getMemoryUsage();
246 newVal = getLongValueFromFile("memory.current");
247 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
248 fail("memory.current", oldVal, newVal);
249 }
250
251 // Memory max has no knowledge of out of band read to "memory.current"
252 // above. Fix that by calling it again.
253 metrics.getMemoryUsage();
254 long memoryMax = metrics.getMemoryMaxUsage();
255 if (memoryMax < memoryMaxUsageMin || memoryMax < newVal) {
256 fail("memoryMaxUsage", "old usages [ " + memoryMaxUsageMin + ", " +
257 newVal + " ] >= " + memoryMax);
258 }
259
260 // Kernel memory
261 verifyNotSupported(metrics.getKernelMemoryFailCount());
262 verifyNotSupported(metrics.getKernelMemoryLimit());
263 verifyNotSupported(metrics.getKernelMemoryMaxUsage());
264 verifyNotSupported(metrics.getKernelMemoryUsage());
265
266 //TCP Memory
267 verifyNotSupported(metrics.getTcpMemoryFailCount());
268 verifyNotSupported(metrics.getTcpMemoryLimit());
269 verifyNotSupported(metrics.getTcpMemoryMaxUsage());
270 verifyNotSupported(metrics.getTcpMemoryUsage());
271
272 // Memory and Swap
273 verifyNotSupported(metrics.getMemoryAndSwapFailCount());
274 verifyNotSupported(metrics.getMemoryAndSwapMaxUsage());
275
276 oldVal = metrics.getMemoryAndSwapLimit();
277 newVal = getLongLimitValueFromFile("memory.swap.max");
278 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
279 fail("memory.swap.max", oldVal, newVal);
280 }
281
282 oldVal = metrics.getMemoryAndSwapUsage();
283 newVal = getLongValueFromFile("memory.swap.current");
284 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
285 fail("memory.swap.current", oldVal, newVal);
286 }
287
288 oldVal = metrics.getMemorySoftLimit();
289 newVal = getLongLimitValueFromFile("memory.high");
290 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
291 fail("memory.high", oldVal, newVal);
292 }
293
294 Asserts.assertFalse(metrics.isMemoryOOMKillEnabled(), "Not supported");
295 }
296
297 @Override
298 public void testCpuAccounting() {
299 Metrics metrics = Metrics.systemMetrics();
300 long oldVal = metrics.getCpuUsage();
301 long newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "usage_usec"));
302
303 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
304 warn("cpu.stat[usage_usec]", oldVal, newVal);
305 }
306
307 verifyPerCpuNotSupported(metrics.getPerCpuUsage());
308
309 oldVal = metrics.getCpuUserUsage();
310 newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "user_usec"));
311 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
312 warn("cpu.stat[user_usec]", oldVal, newVal);
313 }
314
345 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
346 fail("cpu.stat[nr_periods]", oldVal, newVal);
347 }
348
349 oldVal = metrics.getCpuNumThrottled();
350 newVal = getLongValueEntryFromFile("cpu.stat", "nr_throttled");
351 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
352 fail("cpu.stat[nr_throttled]", oldVal, newVal);
353 }
354
355 oldVal = metrics.getCpuThrottledTime();
356 newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "throttled_usec"));
357 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
358 fail("cpu.stat[throttled_usec]", oldVal, newVal);
359 }
360 }
361
362 @Override
363 public void testCpuSets() {
364 Metrics metrics = Metrics.systemMetrics();
365 Integer[] oldVal = Arrays.stream(metrics.getCpuSetCpus()).boxed().toArray(Integer[]::new);
366 Arrays.sort(oldVal);
367
368 String cpusstr = getStringVal("cpuset.cpus");
369 // Parse range string in the format 1,2-6,7
370 Integer[] newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
371 Arrays.sort(newVal);
372 if (Arrays.compare(oldVal, newVal) != 0) {
373 fail("cpuset.cpus", Arrays.toString(oldVal),
374 Arrays.toString(newVal));
375 }
376
377 oldVal = Arrays.stream(metrics.getEffectiveCpuSetCpus()).boxed().toArray(Integer[]::new);
378 Arrays.sort(oldVal);
379 cpusstr = getStringVal("cpuset.cpus.effective");
380 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
381 Arrays.sort(newVal);
382 if (Arrays.compare(oldVal, newVal) != 0) {
383 fail("cpuset.cpus.effective", Arrays.toString(oldVal),
384 Arrays.toString(newVal));
385 }
386
387 oldVal = Arrays.stream(metrics.getCpuSetMems()).boxed().toArray(Integer[]::new);
388 Arrays.sort(oldVal);
389 cpusstr = getStringVal("cpuset.mems");
390 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
391 Arrays.sort(newVal);
392 if (Arrays.compare(oldVal, newVal) != 0) {
393 fail("cpuset.mems", Arrays.toString(oldVal),
394 Arrays.toString(newVal));
395 }
396
397 oldVal = Arrays.stream(metrics.getEffectiveCpuSetMems()).boxed().toArray(Integer[]::new);
398 Arrays.sort(oldVal);
399 cpusstr = getStringVal("cpuset.mems.effective");
400 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
401 Arrays.sort(newVal);
402 if (Arrays.compare(oldVal, newVal) != 0) {
403 fail("cpuset.mems.effective", Arrays.toString(oldVal),
404 Arrays.toString(newVal));
405 }
406
407 verifyNotSupported(metrics.getCpuSetMemoryPressure());
408 Asserts.assertFalse(metrics.isCpuSetMemoryPressureEnabled(), "Should be not supported");
409 }
410
411 @Override
412 public void testCpuConsumption() {
413 Metrics metrics = Metrics.systemMetrics();
414 // make system call
415 long newSysVal = metrics.getCpuSystemUsage();
416 long newUserVal = metrics.getCpuUserUsage();
417 long newUsage = metrics.getCpuUsage();
418
419 verifyPerCpuNotSupported(metrics.getPerCpuUsage());
420
421 // system/user CPU usage counters may be slowly increasing.
422 // allow for equal values for a pass
423 if (newSysVal < startSysVal) {
424 fail("getCpuSystemUsage", newSysVal, startSysVal);
425 }
426
427 // system/user CPU usage counters may be slowly increasing.
428 // allow for equal values for a pass
450 bytes[i] = new byte[8*1024*1024];
451 newMemoryUsage = metrics.getMemoryUsage();
452 if (newMemoryUsage > memoryUsage) {
453 break;
454 }
455 }
456 newMemoryMaxUsage = metrics.getMemoryMaxUsage();
457
458 if (newMemoryMaxUsage < memoryMaxUsage) {
459 fail("getMemoryMaxUsage", memoryMaxUsage,
460 newMemoryMaxUsage);
461 }
462
463 if (newMemoryUsage < memoryUsage) {
464 fail("getMemoryUsage", memoryUsage, newMemoryUsage);
465 }
466 }
467
468 @Override
469 public void testMisc() {
470 // nothing for cgroups v2
471 }
472
473 }
|
1 /*
2 * Copyright (c) 2020, Red Hat Inc.
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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
132 }
133 }
134
135 private String getStringVal(String file) {
136 Path filePath = Paths.get(UNIFIED.getPath(), file);
137 try {
138 return Files.lines(filePath).collect(Collectors.joining());
139 } catch (IOException e) {
140 return null;
141 }
142 }
143
144 private void fail(String metric, long oldVal, long newVal) {
145 CgroupMetricsTester.fail(UnifiedController.NAME, metric, oldVal, newVal);
146 }
147
148 private void fail(String metric, String oldVal, String newVal) {
149 CgroupMetricsTester.fail(UnifiedController.NAME, metric, oldVal, newVal);
150 }
151
152 private void warn(String metric, long oldVal, long newVal) {
153 CgroupMetricsTester.warn(UnifiedController.NAME, metric, oldVal, newVal);
154 }
155
156 private void verifyNotSupported(long metricVal) {
157 Asserts.assertEquals(metricVal, NOT_SUPPORTED, "Expected metric to be not supported!");
158 }
159
160 private void verifyNotSupported(double metricVal) {
161 if (!CgroupMetricsTester.compareWithErrorMargin(NOT_SUPPORTED, metricVal)) {
162 throw new RuntimeException("Metric not supported, got: " + metricVal +
163 " expected: " + NOT_SUPPORTED);
164 }
165 }
166
167 private void verifyPerCpuNotSupported(long[] perCpuUsage) {
168 Asserts.assertNull(perCpuUsage, "perCpuUsage expected to be not supported");
169 }
170
171 private long getCpuShares(String file) {
172 long rawVal = getLongValueFromFile(file);
173 if (rawVal == 0 || rawVal == 100) {
174 return UNLIMITED;
175 }
176 int shares = (int)rawVal;
177 // CPU shares (OCI) value needs to get translated into
178 // a proper Cgroups v2 value. See:
179 // https://github.com/containers/crun/blob/master/crun.1.md#cpu-controller
180 //
181 // Use the inverse of (x == OCI value, y == cgroupsv2 value):
182 // ((262142 * y - 1)/9999) + 2 = x
183 //
184 int x = 262142 * shares - 1;
185 double frac = x/9999.0;
186 x = ((int)frac) + 2;
187 if ( x <= PER_CPU_SHARES ) {
188 return PER_CPU_SHARES; // mimic cgroups v1
189 }
190 int f = x/PER_CPU_SHARES;
191 int lower_multiple = f * PER_CPU_SHARES;
192 int upper_multiple = (f + 1) * PER_CPU_SHARES;
193 int distance_lower = Math.max(lower_multiple, x) - Math.min(lower_multiple, x);
194 int distance_upper = Math.max(upper_multiple, x) - Math.min(upper_multiple, x);
195 x = distance_lower <= distance_upper ? lower_multiple : upper_multiple;
196 return x;
197 }
198
199 private long getCpuMaxValueFromFile(String file) {
200 return getCpuValueFromFile(file, 0 /* $MAX index */);
201 }
202
203 private long getCpuPeriodValueFromFile(String file) {
204 return getCpuValueFromFile(file, 1 /* $PERIOD index */);
205 }
206
207 private long getCpuValueFromFile(String file, int index) {
208 String maxPeriod = getStringVal(file);
209 if (maxPeriod == null) {
210 return UNLIMITED;
211 }
212 String[] tokens = maxPeriod.split("\\s+");
213 String val = tokens[index];
214 if (MAX.equals(val)) {
215 return UNLIMITED;
216 }
217 return convertStringToLong(val);
218 }
219
220 private long convertStringToLong(String val) {
221 return CgroupMetricsTester.convertStringToLong(val, UNLIMITED);
222 }
223
224 @Override
225 public void testMemorySubsystem() {
226 Metrics metrics = Metrics.systemMetrics();
227
228 // User Memory
229 long oldVal = metrics.getMemoryFailCount();
230 long newVal = getLongValueEntryFromFile("memory.events", "max");
231 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
232 fail("memory.events[max]", oldVal, newVal);
233 }
234
235 oldVal = metrics.getMemoryLimit();
236 newVal = getLongLimitValueFromFile("memory.max");
237 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
238 fail("memory.max", oldVal, newVal);
239 }
240
241 oldVal = metrics.getMemoryUsage();
242 newVal = getLongValueFromFile("memory.current");
243 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
244 fail("memory.current", oldVal, newVal);
245 }
246 verifyNotSupported(metrics.getMemoryMaxUsage());
247
248 // Kernel memory
249 verifyNotSupported(metrics.getKernelMemoryFailCount());
250 verifyNotSupported(metrics.getKernelMemoryLimit());
251 verifyNotSupported(metrics.getKernelMemoryMaxUsage());
252 verifyNotSupported(metrics.getKernelMemoryUsage());
253
254 //TCP Memory
255 verifyNotSupported(metrics.getTcpMemoryFailCount());
256 verifyNotSupported(metrics.getTcpMemoryLimit());
257 verifyNotSupported(metrics.getTcpMemoryMaxUsage());
258
259 oldVal = metrics.getTcpMemoryUsage();
260 newVal = getLongValueEntryFromFile("memory.stat", "sock");
261 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
262 fail("memory.stat[sock]", oldVal, newVal);
263 }
264
265 // Memory and Swap
266 verifyNotSupported(metrics.getMemoryAndSwapFailCount());
267 verifyNotSupported(metrics.getMemoryAndSwapMaxUsage());
268
269 oldVal = metrics.getMemoryAndSwapLimit();
270 newVal = getLongLimitValueFromFile("memory.swap.max");
271 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
272 fail("memory.swap.max", oldVal, newVal);
273 }
274
275 oldVal = metrics.getMemoryAndSwapUsage();
276 newVal = getLongValueFromFile("memory.swap.current");
277 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
278 fail("memory.swap.current", oldVal, newVal);
279 }
280
281 oldVal = metrics.getMemorySoftLimit();
282 newVal = getLongLimitValueFromFile("memory.high");
283 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
284 fail("memory.high", oldVal, newVal);
285 }
286
287 Asserts.assertNull(metrics.isMemoryOOMKillEnabled(), "Not supported");
288 }
289
290 @Override
291 public void testCpuAccounting() {
292 Metrics metrics = Metrics.systemMetrics();
293 long oldVal = metrics.getCpuUsage();
294 long newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "usage_usec"));
295
296 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
297 warn("cpu.stat[usage_usec]", oldVal, newVal);
298 }
299
300 verifyPerCpuNotSupported(metrics.getPerCpuUsage());
301
302 oldVal = metrics.getCpuUserUsage();
303 newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "user_usec"));
304 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
305 warn("cpu.stat[user_usec]", oldVal, newVal);
306 }
307
338 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
339 fail("cpu.stat[nr_periods]", oldVal, newVal);
340 }
341
342 oldVal = metrics.getCpuNumThrottled();
343 newVal = getLongValueEntryFromFile("cpu.stat", "nr_throttled");
344 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
345 fail("cpu.stat[nr_throttled]", oldVal, newVal);
346 }
347
348 oldVal = metrics.getCpuThrottledTime();
349 newVal = TimeUnit.MICROSECONDS.toNanos(getLongValueEntryFromFile("cpu.stat", "throttled_usec"));
350 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
351 fail("cpu.stat[throttled_usec]", oldVal, newVal);
352 }
353 }
354
355 @Override
356 public void testCpuSets() {
357 Metrics metrics = Metrics.systemMetrics();
358 int[] cpus = mapNullToEmpty(metrics.getCpuSetCpus());
359 Integer[] oldVal = Arrays.stream(cpus).boxed().toArray(Integer[]::new);
360 Arrays.sort(oldVal);
361
362 String cpusstr = getStringVal("cpuset.cpus");
363 // Parse range string in the format 1,2-6,7
364 Integer[] newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
365 Arrays.sort(newVal);
366 if (Arrays.compare(oldVal, newVal) != 0) {
367 fail("cpuset.cpus", Arrays.toString(oldVal),
368 Arrays.toString(newVal));
369 }
370
371 cpus = mapNullToEmpty(metrics.getEffectiveCpuSetCpus());
372 oldVal = Arrays.stream(cpus).boxed().toArray(Integer[]::new);
373 Arrays.sort(oldVal);
374 cpusstr = getStringVal("cpuset.cpus.effective");
375 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
376 Arrays.sort(newVal);
377 if (Arrays.compare(oldVal, newVal) != 0) {
378 fail("cpuset.cpus.effective", Arrays.toString(oldVal),
379 Arrays.toString(newVal));
380 }
381
382 cpus = mapNullToEmpty(metrics.getCpuSetMems());
383 oldVal = Arrays.stream(cpus).boxed().toArray(Integer[]::new);
384 Arrays.sort(oldVal);
385 cpusstr = getStringVal("cpuset.mems");
386 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
387 Arrays.sort(newVal);
388 if (Arrays.compare(oldVal, newVal) != 0) {
389 fail("cpuset.mems", Arrays.toString(oldVal),
390 Arrays.toString(newVal));
391 }
392
393 cpus = mapNullToEmpty(metrics.getEffectiveCpuSetMems());
394 oldVal = Arrays.stream(cpus).boxed().toArray(Integer[]::new);
395 Arrays.sort(oldVal);
396 cpusstr = getStringVal("cpuset.mems.effective");
397 newVal = CgroupMetricsTester.convertCpuSetsToArray(cpusstr);
398 Arrays.sort(newVal);
399 if (Arrays.compare(oldVal, newVal) != 0) {
400 fail("cpuset.mems.effective", Arrays.toString(oldVal),
401 Arrays.toString(newVal));
402 }
403
404 verifyNotSupported(metrics.getCpuSetMemoryPressure());
405 Asserts.assertNull(metrics.isCpuSetMemoryPressureEnabled(), "Should be not supported");
406 }
407
408 private int[] mapNullToEmpty(int[] cpus) {
409 if (cpus == null) {
410 // Not available. For sake of testing continue with an
411 // empty array.
412 cpus = new int[0];
413 }
414 return cpus;
415 }
416
417 @Override
418 public void testCpuConsumption() {
419 Metrics metrics = Metrics.systemMetrics();
420 // make system call
421 long newSysVal = metrics.getCpuSystemUsage();
422 long newUserVal = metrics.getCpuUserUsage();
423 long newUsage = metrics.getCpuUsage();
424
425 verifyPerCpuNotSupported(metrics.getPerCpuUsage());
426
427 // system/user CPU usage counters may be slowly increasing.
428 // allow for equal values for a pass
429 if (newSysVal < startSysVal) {
430 fail("getCpuSystemUsage", newSysVal, startSysVal);
431 }
432
433 // system/user CPU usage counters may be slowly increasing.
434 // allow for equal values for a pass
456 bytes[i] = new byte[8*1024*1024];
457 newMemoryUsage = metrics.getMemoryUsage();
458 if (newMemoryUsage > memoryUsage) {
459 break;
460 }
461 }
462 newMemoryMaxUsage = metrics.getMemoryMaxUsage();
463
464 if (newMemoryMaxUsage < memoryMaxUsage) {
465 fail("getMemoryMaxUsage", memoryMaxUsage,
466 newMemoryMaxUsage);
467 }
468
469 if (newMemoryUsage < memoryUsage) {
470 fail("getMemoryUsage", memoryUsage, newMemoryUsage);
471 }
472 }
473
474 @Override
475 public void testMisc() {
476 testIOStat();
477 }
478
479 private void testIOStat() {
480 Metrics metrics = Metrics.systemMetrics();
481 long oldVal = metrics.getBlkIOServiceCount();
482 long newVal = getIoStatAccumulate(new String[] { "rios", "wios" });
483 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
484 fail("io.stat->rios/wios: ", oldVal, newVal);
485 }
486
487 oldVal = metrics.getBlkIOServiced();
488 newVal = getIoStatAccumulate(new String[] { "rbytes", "wbytes" });
489 if (!CgroupMetricsTester.compareWithErrorMargin(oldVal, newVal)) {
490 fail("io.stat->rbytes/wbytes: ", oldVal, newVal);
491 }
492 }
493
494 private long getIoStatAccumulate(String[] matchNames) {
495 try {
496 return Files.lines(Paths.get(UNIFIED.getPath(), "io.stat"))
497 .map(line -> {
498 long accumulator = 0;
499 String[] tokens = line.split("\\s+");
500 for (String t: tokens) {
501 String[] keyVal = t.split("=");
502 if (keyVal.length != 2) {
503 continue;
504 }
505 for (String match: matchNames) {
506 if (match.equals(keyVal[0])) {
507 accumulator += Long.parseLong(keyVal[1]);
508 }
509 }
510 }
511 return accumulator;
512 }).collect(Collectors.summingLong(e -> e));
513 } catch (IOException e) {
514 return Metrics.LONG_RETVAL_NOT_SUPPORTED;
515 }
516 }
517 }
|