@@ -43,7 +43,7 @@ public void testOsInfo() throws IOException {
43
43
final OsProbe osProbe = new OsProbe () {
44
44
45
45
@ Override
46
- List <String > readOsRelease () throws IOException {
46
+ List <String > readOsRelease () {
47
47
assert Constants .LINUX : Constants .OS_NAME ;
48
48
if (prettyName != null ) {
49
49
final String quote = randomFrom ("\" " , "'" , "" );
@@ -78,8 +78,10 @@ public void testOsStats() {
78
78
OsStats stats = osProbe .osStats ();
79
79
assertNotNull (stats );
80
80
assertThat (stats .getTimestamp (), greaterThan (0L ));
81
- assertThat (stats .getCpu ().getPercent (), anyOf (equalTo ((short ) -1 ),
82
- is (both (greaterThanOrEqualTo ((short ) 0 )).and (lessThanOrEqualTo ((short ) 100 )))));
81
+ assertThat (
82
+ stats .getCpu ().getPercent (),
83
+ anyOf (equalTo ((short ) -1 ), is (both (greaterThanOrEqualTo ((short ) 0 )).and (lessThanOrEqualTo ((short ) 100 ))))
84
+ );
83
85
double [] loadAverage = stats .getCpu ().getLoadAverage ();
84
86
if (loadAverage != null ) {
85
87
assertThat (loadAverage .length , equalTo (3 ));
@@ -141,8 +143,11 @@ public void testOsStats() {
141
143
assertThat (stats .getCgroup ().getCpuStat ().getTimeThrottledNanos (), greaterThanOrEqualTo (0L ));
142
144
// These could be null if transported from a node running an older version, but shouldn't be null on the current node
143
145
assertThat (stats .getCgroup ().getMemoryControlGroup (), notNullValue ());
144
- assertThat (stats .getCgroup ().getMemoryLimitInBytes (), notNullValue ());
145
- assertThat (new BigInteger (stats .getCgroup ().getMemoryLimitInBytes ()), greaterThan (BigInteger .ZERO ));
146
+ String memoryLimitInBytes = stats .getCgroup ().getMemoryLimitInBytes ();
147
+ assertThat (memoryLimitInBytes , notNullValue ());
148
+ if (memoryLimitInBytes .equals ("max" ) == false ) {
149
+ assertThat (new BigInteger (memoryLimitInBytes ), greaterThan (BigInteger .ZERO ));
150
+ }
146
151
assertThat (stats .getCgroup ().getMemoryUsageInBytes (), notNullValue ());
147
152
assertThat (new BigInteger (stats .getCgroup ().getMemoryUsageInBytes ()), greaterThan (BigInteger .ZERO ));
148
153
}
@@ -173,16 +178,14 @@ String readProcLoadavg() {
173
178
}
174
179
175
180
public void testCgroupProbe () {
176
- assumeTrue ("test runs on Linux only" , Constants .LINUX );
177
-
178
- final boolean areCgroupStatsAvailable = randomBoolean ();
181
+ final int availableCgroupsVersion = randomFrom (0 , 1 , 2 );
179
182
final String hierarchy = randomAlphaOfLength (16 );
180
183
181
- final OsProbe probe = buildStubOsProbe (areCgroupStatsAvailable , hierarchy );
184
+ final OsProbe probe = buildStubOsProbe (availableCgroupsVersion , hierarchy );
182
185
183
186
final OsStats .Cgroup cgroup = probe .osStats ().getCgroup ();
184
187
185
- if (areCgroupStatsAvailable ) {
188
+ if (availableCgroupsVersion > 0 ) {
186
189
assertNotNull (cgroup );
187
190
assertThat (cgroup .getCpuAcctControlGroup (), equalTo ("/" + hierarchy ));
188
191
assertThat (cgroup .getCpuAcctUsageNanos (), equalTo (364869866063112L ));
@@ -200,61 +203,53 @@ public void testCgroupProbe() {
200
203
}
201
204
202
205
public void testCgroupProbeWithMissingCpuAcct () {
203
- assumeTrue ("test runs on Linux only" , Constants .LINUX );
204
-
205
206
final String hierarchy = randomAlphaOfLength (16 );
206
207
207
208
// This cgroup data is missing a line about cpuacct
208
- List <String > procSelfCgroupLines = getProcSelfGroupLines (hierarchy )
209
- .stream ()
209
+ List <String > procSelfCgroupLines = getProcSelfGroupLines (1 , hierarchy ).stream ()
210
210
.map (line -> line .replaceFirst (",cpuacct" , "" ))
211
211
.collect (Collectors .toList ());
212
212
213
- final OsProbe probe = buildStubOsProbe (true , hierarchy , procSelfCgroupLines );
213
+ final OsProbe probe = buildStubOsProbe (1 , hierarchy , procSelfCgroupLines );
214
214
215
215
final OsStats .Cgroup cgroup = probe .osStats ().getCgroup ();
216
216
217
217
assertNull (cgroup );
218
218
}
219
219
220
220
public void testCgroupProbeWithMissingCpu () {
221
- assumeTrue ("test runs on Linux only" , Constants .LINUX );
222
-
223
221
final String hierarchy = randomAlphaOfLength (16 );
224
222
225
223
// This cgroup data is missing a line about cpu
226
- List <String > procSelfCgroupLines = getProcSelfGroupLines (hierarchy )
227
- .stream ()
224
+ List <String > procSelfCgroupLines = getProcSelfGroupLines (1 , hierarchy ).stream ()
228
225
.map (line -> line .replaceFirst (":cpu," , ":" ))
229
226
.collect (Collectors .toList ());
230
227
231
-
232
- final OsProbe probe = buildStubOsProbe (true , hierarchy , procSelfCgroupLines );
228
+ final OsProbe probe = buildStubOsProbe (1 , hierarchy , procSelfCgroupLines );
233
229
234
230
final OsStats .Cgroup cgroup = probe .osStats ().getCgroup ();
235
231
236
232
assertNull (cgroup );
237
233
}
238
234
239
235
public void testCgroupProbeWithMissingMemory () {
240
- assumeTrue ("test runs on Linux only" , Constants .LINUX );
241
-
242
236
final String hierarchy = randomAlphaOfLength (16 );
243
237
244
238
// This cgroup data is missing a line about memory
245
- List <String > procSelfCgroupLines = getProcSelfGroupLines (hierarchy )
246
- .stream ()
239
+ List <String > procSelfCgroupLines = getProcSelfGroupLines (1 , hierarchy ).stream ()
247
240
.filter (line -> line .contains (":memory:" ) == false )
248
241
.collect (Collectors .toList ());
249
242
250
- final OsProbe probe = buildStubOsProbe (true , hierarchy , procSelfCgroupLines );
243
+ final OsProbe probe = buildStubOsProbe (1 , hierarchy , procSelfCgroupLines );
251
244
252
245
final OsStats .Cgroup cgroup = probe .osStats ().getCgroup ();
253
246
254
247
assertNull (cgroup );
255
248
}
256
249
257
250
public void testGetTotalMemFromProcMeminfo () throws Exception {
251
+ int cgroupsVersion = randomFrom (1 , 2 );
252
+
258
253
// missing MemTotal line
259
254
List <String > meminfoLines = Arrays .asList (
260
255
"MemFree: 8467692 kB" ,
@@ -265,7 +260,7 @@ public void testGetTotalMemFromProcMeminfo() throws Exception {
265
260
"Active: 43637908 kB" ,
266
261
"Inactive: 8130280 kB"
267
262
);
268
- OsProbe probe = buildStubOsProbe (true , "" , org .elasticsearch .core .List .of (), meminfoLines );
263
+ OsProbe probe = buildStubOsProbe (cgroupsVersion , "" , org .elasticsearch .core .List .of (), meminfoLines );
269
264
assertThat (probe .getTotalMemFromProcMeminfo (), equalTo (0L ));
270
265
271
266
// MemTotal line with invalid value
@@ -279,7 +274,7 @@ public void testGetTotalMemFromProcMeminfo() throws Exception {
279
274
"Active: 43637908 kB" ,
280
275
"Inactive: 8130280 kB"
281
276
);
282
- probe = buildStubOsProbe (true , "" , org .elasticsearch .core .List .of (), meminfoLines );
277
+ probe = buildStubOsProbe (cgroupsVersion , "" , org .elasticsearch .core .List .of (), meminfoLines );
283
278
assertThat (probe .getTotalMemFromProcMeminfo (), equalTo (0L ));
284
279
285
280
// MemTotal line with invalid unit
@@ -293,7 +288,7 @@ public void testGetTotalMemFromProcMeminfo() throws Exception {
293
288
"Active: 43637908 kB" ,
294
289
"Inactive: 8130280 kB"
295
290
);
296
- probe = buildStubOsProbe (true , "" , org .elasticsearch .core .List .of (), meminfoLines );
291
+ probe = buildStubOsProbe (cgroupsVersion , "" , org .elasticsearch .core .List .of (), meminfoLines );
297
292
assertThat (probe .getTotalMemFromProcMeminfo (), equalTo (0L ));
298
293
299
294
// MemTotal line with random valid value
@@ -308,7 +303,7 @@ public void testGetTotalMemFromProcMeminfo() throws Exception {
308
303
"Active: 43637908 kB" ,
309
304
"Inactive: 8130280 kB"
310
305
);
311
- probe = buildStubOsProbe (true , "" , org .elasticsearch .core .List .of (), meminfoLines );
306
+ probe = buildStubOsProbe (cgroupsVersion , "" , org .elasticsearch .core .List .of (), meminfoLines );
312
307
assertThat (probe .getTotalMemFromProcMeminfo (), equalTo (memTotalInKb * 1024L ));
313
308
}
314
309
@@ -319,7 +314,13 @@ public void testGetTotalMemoryOnDebian8() throws Exception {
319
314
assertThat (osProbe .getTotalPhysicalMemorySize (), greaterThan (0L ));
320
315
}
321
316
322
- private static List <String > getProcSelfGroupLines (String hierarchy ) {
317
+ private static List <String > getProcSelfGroupLines (int cgroupsVersion , String hierarchy ) {
318
+ // It doesn't really matter if cgroupsVersion == 0 here
319
+
320
+ if (cgroupsVersion == 2 ) {
321
+ return org .elasticsearch .core .List .of ("0::/" + hierarchy );
322
+ }
323
+
323
324
return Arrays .asList (
324
325
"10:freezer:/" ,
325
326
"9:net_cls,net_prio:/" ,
@@ -331,32 +332,40 @@ private static List<String> getProcSelfGroupLines(String hierarchy) {
331
332
"3:perf_event:/" ,
332
333
"2:cpu,cpuacct,cpuset:/" + hierarchy ,
333
334
"1:name=systemd:/user.slice/user-1000.slice/session-2359.scope" ,
334
- "0::/cgroup2" );
335
+ "0::/cgroup2"
336
+ );
335
337
}
336
338
337
- private static OsProbe buildStubOsProbe (final boolean areCgroupStatsAvailable , final String hierarchy ) {
338
- List <String > procSelfCgroupLines = getProcSelfGroupLines (hierarchy );
339
+ private static OsProbe buildStubOsProbe (final int availableCgroupsVersion , final String hierarchy ) {
340
+ List <String > procSelfCgroupLines = getProcSelfGroupLines (availableCgroupsVersion , hierarchy );
339
341
340
- return buildStubOsProbe (areCgroupStatsAvailable , hierarchy , procSelfCgroupLines );
342
+ return buildStubOsProbe (availableCgroupsVersion , hierarchy , procSelfCgroupLines );
341
343
}
342
344
343
345
/**
344
346
* Builds a test instance of OsProbe. Methods that ordinarily read from the filesystem are overridden to return values based upon
345
347
* the arguments to this method.
346
348
*
347
- * @param areCgroupStatsAvailable whether or not cgroup data is available. Normally OsProbe establishes this for itself.
349
+ * @param availableCgroupsVersion what version of cgroups are available, 1 or 2, or 0 for no cgroups. Normally OsProbe establishes this
350
+ * for itself.
348
351
* @param hierarchy a mock value used to generate a cgroup hierarchy.
349
352
* @param procSelfCgroupLines the lines that will be used as the content of <code>/proc/self/cgroup</code>
350
353
* @param procMeminfoLines lines that will be used as the content of <code>/proc/meminfo</code>
351
354
* @return a test instance
352
355
*/
353
356
private static OsProbe buildStubOsProbe (
354
- final boolean areCgroupStatsAvailable ,
357
+ final int availableCgroupsVersion ,
355
358
final String hierarchy ,
356
359
List <String > procSelfCgroupLines ,
357
360
List <String > procMeminfoLines
358
361
) {
359
362
return new OsProbe () {
363
+ @ Override
364
+ OsStats .Cgroup getCgroup (boolean isLinux ) {
365
+ // Pretend we're always on Linux so that we can run the cgroup tests
366
+ return super .getCgroup (true );
367
+ }
368
+
360
369
@ Override
361
370
List <String > readProcSelfCgroup () {
362
371
return procSelfCgroupLines ;
@@ -382,10 +391,7 @@ String readSysFsCgroupCpuAcctCpuAcctCfsQuota(String controlGroup) {
382
391
383
392
@ Override
384
393
List <String > readSysFsCgroupCpuAcctCpuStat (String controlGroup ) {
385
- return Arrays .asList (
386
- "nr_periods 17992" ,
387
- "nr_throttled 1311" ,
388
- "throttled_time 139298645489" );
394
+ return Arrays .asList ("nr_periods 17992" , "nr_throttled 1311" , "throttled_time 139298645489" );
389
395
}
390
396
391
397
@ Override
@@ -403,22 +409,50 @@ String readSysFsCgroupMemoryUsageInBytes(String controlGroup) {
403
409
404
410
@ Override
405
411
boolean areCgroupStatsAvailable () {
406
- return areCgroupStatsAvailable ;
412
+ return availableCgroupsVersion > 0 ;
407
413
}
408
414
409
415
@ Override
410
- List <String > readProcMeminfo () throws IOException {
416
+ List <String > readProcMeminfo () {
411
417
return procMeminfoLines ;
412
418
}
419
+
420
+ @ Override
421
+ String readSysFsCgroupV2MemoryLimitInBytes (String controlGroup ) {
422
+ assertThat (controlGroup , equalTo ("/" + hierarchy ));
423
+ // This is the highest value that can be stored in an unsigned 64 bit number, hence too big for long
424
+ return "18446744073709551615" ;
425
+ }
426
+
427
+ @ Override
428
+ String readSysFsCgroupV2MemoryUsageInBytes (String controlGroup ) {
429
+ assertThat (controlGroup , equalTo ("/" + hierarchy ));
430
+ return "4796416" ;
431
+ }
432
+
433
+ @ Override
434
+ List <String > readCgroupV2CpuStats (String controlGroup ) {
435
+ assertThat (controlGroup , equalTo ("/" + hierarchy ));
436
+ return org .elasticsearch .core .List .of (
437
+ "usage_usec 364869866063112" ,
438
+ "user_usec 34636" ,
439
+ "system_usec 9896" ,
440
+ "nr_periods 17992" ,
441
+ "nr_throttled 1311" ,
442
+ "throttled_usec 139298645489"
443
+ );
444
+ }
445
+
446
+ @ Override
447
+ String readCgroupV2CpuLimit (String controlGroup ) {
448
+ assertThat (controlGroup , equalTo ("/" + hierarchy ));
449
+ return "50000 100000" ;
450
+ }
413
451
};
414
452
}
415
453
416
- private static OsProbe buildStubOsProbe (
417
- final boolean areCgroupStatsAvailable ,
418
- final String hierarchy ,
419
- List <String > procSelfCgroupLines
420
- ) {
421
- return buildStubOsProbe (areCgroupStatsAvailable , hierarchy , procSelfCgroupLines , org .elasticsearch .core .List .of ());
454
+ private static OsProbe buildStubOsProbe (final int availableCgroupsVersion , final String hierarchy , List <String > procSelfCgroupLines ) {
455
+ return buildStubOsProbe (availableCgroupsVersion , hierarchy , procSelfCgroupLines , org .elasticsearch .core .List .of ());
422
456
}
423
457
424
458
}
0 commit comments