9
9
import pytest
10
10
import requests
11
11
12
- from framework .utils import check_output , get_free_mem_ssh
12
+ from framework .utils import get_resident_memory
13
13
14
14
STATS_POLLING_INTERVAL_S = 1
15
15
16
16
17
- def get_stable_rss_mem_by_pid ( pid , percentage_delta = 1 ):
17
+ def get_stable_rss_mem ( uvm , percentage_delta = 1 ):
18
18
"""
19
19
Get the RSS memory that a guest uses, given the pid of the guest.
20
20
21
21
Wait till the fluctuations in RSS drop below percentage_delta.
22
22
Or print a warning if this does not happen.
23
23
"""
24
24
25
- # All values are reported as KiB
26
-
27
- def get_rss_from_pmap ():
28
- _ , output , _ = check_output ("pmap -X {}" .format (pid ))
29
- return int (output .split ("\n " )[- 2 ].split ()[1 ], 10 )
30
-
31
25
first_rss = 0
32
26
second_rss = 0
33
27
for _ in range (5 ):
34
- first_rss = get_rss_from_pmap ( )
28
+ first_rss = get_resident_memory ( uvm . ps )
35
29
time .sleep (1 )
36
- second_rss = get_rss_from_pmap ( )
30
+ second_rss = get_resident_memory ( uvm . ps )
37
31
abs_diff = abs (first_rss - second_rss )
38
32
abs_delta = abs_diff / first_rss * 100
39
33
print (
40
- f"RSS readings: old: { first_rss } new: { second_rss } abs_diff: { abs_diff } abs_delta: { abs_delta } "
34
+ f"RSS readings (bytes) : old: { first_rss } new: { second_rss } abs_diff: { abs_diff } abs_delta: { abs_delta } "
41
35
)
42
36
if abs_delta < percentage_delta :
43
37
return second_rss
@@ -87,25 +81,24 @@ def make_guest_dirty_memory(ssh_connection, amount_mib=32):
87
81
def _test_rss_memory_lower (test_microvm ):
88
82
"""Check inflating the balloon makes guest use less rss memory."""
89
83
# Get the firecracker pid, and open an ssh connection.
90
- firecracker_pid = test_microvm .firecracker_pid
91
84
ssh_connection = test_microvm .ssh
92
85
93
86
# Using deflate_on_oom, get the RSS as low as possible
94
87
test_microvm .api .balloon .patch (amount_mib = 200 )
95
88
96
89
# Get initial rss consumption.
97
- init_rss = get_stable_rss_mem_by_pid ( firecracker_pid )
90
+ init_rss = get_stable_rss_mem ( test_microvm )
98
91
99
92
# Get the balloon back to 0.
100
93
test_microvm .api .balloon .patch (amount_mib = 0 )
101
94
# This call will internally wait for rss to become stable.
102
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
95
+ _ = get_stable_rss_mem ( test_microvm )
103
96
104
97
# Dirty memory, then inflate balloon and get ballooned rss consumption.
105
98
make_guest_dirty_memory (ssh_connection , amount_mib = 32 )
106
99
107
100
test_microvm .api .balloon .patch (amount_mib = 200 )
108
- balloon_rss = get_stable_rss_mem_by_pid ( firecracker_pid )
101
+ balloon_rss = get_stable_rss_mem ( test_microvm )
109
102
110
103
# Check that the ballooning reclaimed the memory.
111
104
assert balloon_rss - init_rss <= 15000
@@ -157,7 +150,7 @@ def test_inflate_reduces_free(uvm_plain_any):
157
150
# Inflate 64 MB == 16384 page balloon.
158
151
test_microvm .api .balloon .patch (amount_mib = 64 )
159
152
# This call will internally wait for rss to become stable.
160
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
153
+ _ = get_stable_rss_mem ( test_microvm . ps )
161
154
162
155
# Get the free memory after ballooning.
163
156
available_mem_inflated = get_free_mem_ssh (test_microvm .ssh )
@@ -195,19 +188,18 @@ def test_deflate_on_oom(uvm_plain_any, deflate_on_oom):
195
188
196
189
# Start the microvm.
197
190
test_microvm .start ()
198
- firecracker_pid = test_microvm .firecracker_pid
199
191
200
192
# We get an initial reading of the RSS, then calculate the amount
201
193
# we need to inflate the balloon with by subtracting it from the
202
194
# VM size and adding an offset of 50 MiB in order to make sure we
203
195
# get a lower reading than the initial one.
204
- initial_rss = get_stable_rss_mem_by_pid ( firecracker_pid )
196
+ initial_rss = get_stable_rss_mem ( test_microvm )
205
197
inflate_size = 256 - (int (initial_rss / 1024 ) + 50 )
206
198
207
199
# Inflate the balloon
208
200
test_microvm .api .balloon .patch (amount_mib = inflate_size )
209
201
# This call will internally wait for rss to become stable.
210
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
202
+ _ = get_stable_rss_mem ( test_microvm )
211
203
212
204
# Check that using memory leads to the balloon device automatically
213
205
# deflate (or not).
@@ -250,39 +242,38 @@ def test_reinflate_balloon(uvm_plain_any):
250
242
251
243
# Start the microvm.
252
244
test_microvm .start ()
253
- firecracker_pid = test_microvm .firecracker_pid
254
245
255
246
# First inflate the balloon to free up the uncertain amount of memory
256
247
# used by the kernel at boot and establish a baseline, then give back
257
248
# the memory.
258
249
test_microvm .api .balloon .patch (amount_mib = 200 )
259
250
# This call will internally wait for rss to become stable.
260
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
251
+ _ = get_stable_rss_mem ( test_microvm )
261
252
262
253
test_microvm .api .balloon .patch (amount_mib = 0 )
263
254
# This call will internally wait for rss to become stable.
264
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
255
+ _ = get_stable_rss_mem ( test_microvm )
265
256
266
257
# Get the guest to dirty memory.
267
258
make_guest_dirty_memory (test_microvm .ssh , amount_mib = 32 )
268
- first_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
259
+ first_reading = get_stable_rss_mem ( test_microvm )
269
260
270
261
# Now inflate the balloon.
271
262
test_microvm .api .balloon .patch (amount_mib = 200 )
272
- second_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
263
+ second_reading = get_stable_rss_mem ( test_microvm )
273
264
274
265
# Now deflate the balloon.
275
266
test_microvm .api .balloon .patch (amount_mib = 0 )
276
267
# This call will internally wait for rss to become stable.
277
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
268
+ _ = get_stable_rss_mem ( test_microvm )
278
269
279
270
# Now have the guest dirty memory again.
280
271
make_guest_dirty_memory (test_microvm .ssh , amount_mib = 32 )
281
- third_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
272
+ third_reading = get_stable_rss_mem ( test_microvm )
282
273
283
274
# Now inflate the balloon again.
284
275
test_microvm .api .balloon .patch (amount_mib = 200 )
285
- fourth_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
276
+ fourth_reading = get_stable_rss_mem ( test_microvm )
286
277
287
278
# Check that the memory used is the same after regardless of the previous
288
279
# inflate history of the balloon (with the third reading being allowed
@@ -309,10 +300,9 @@ def test_size_reduction(uvm_plain_any):
309
300
310
301
# Start the microvm.
311
302
test_microvm .start ()
312
- firecracker_pid = test_microvm .firecracker_pid
313
303
314
304
# Check memory usage.
315
- first_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
305
+ first_reading = get_stable_rss_mem ( test_microvm )
316
306
317
307
# Have the guest drop its caches.
318
308
test_microvm .ssh .run ("sync; echo 3 > /proc/sys/vm/drop_caches" )
@@ -328,7 +318,7 @@ def test_size_reduction(uvm_plain_any):
328
318
test_microvm .api .balloon .patch (amount_mib = inflate_size )
329
319
330
320
# Check memory usage again.
331
- second_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
321
+ second_reading = get_stable_rss_mem ( test_microvm )
332
322
333
323
# There should be a reduction of at least 10MB.
334
324
assert first_reading - second_reading >= 10000
@@ -353,7 +343,6 @@ def test_stats(uvm_plain_any):
353
343
354
344
# Start the microvm.
355
345
test_microvm .start ()
356
- firecracker_pid = test_microvm .firecracker_pid
357
346
358
347
# Give Firecracker enough time to poll the stats at least once post-boot
359
348
time .sleep (STATS_POLLING_INTERVAL_S * 2 )
@@ -371,7 +360,7 @@ def test_stats(uvm_plain_any):
371
360
make_guest_dirty_memory (test_microvm .ssh , amount_mib = 10 )
372
361
time .sleep (1 )
373
362
# This call will internally wait for rss to become stable.
374
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
363
+ _ = get_stable_rss_mem ( test_microvm )
375
364
376
365
# Make sure that the stats catch the page faults.
377
366
after_workload_stats = test_microvm .api .balloon_stats .get ().json ()
@@ -380,7 +369,7 @@ def test_stats(uvm_plain_any):
380
369
# Now inflate the balloon with 10MB of pages.
381
370
test_microvm .api .balloon .patch (amount_mib = 10 )
382
371
# This call will internally wait for rss to become stable.
383
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
372
+ _ = get_stable_rss_mem ( test_microvm )
384
373
385
374
# Get another reading of the stats after the polling interval has passed.
386
375
inflated_stats = test_microvm .api .balloon_stats .get ().json ()
@@ -393,7 +382,7 @@ def test_stats(uvm_plain_any):
393
382
# available memory.
394
383
test_microvm .api .balloon .patch (amount_mib = 0 )
395
384
# This call will internally wait for rss to become stable.
396
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
385
+ _ = get_stable_rss_mem ( test_microvm )
397
386
398
387
# Get another reading of the stats after the polling interval has passed.
399
388
deflated_stats = test_microvm .api .balloon_stats .get ().json ()
@@ -421,13 +410,12 @@ def test_stats_update(uvm_plain_any):
421
410
422
411
# Start the microvm.
423
412
test_microvm .start ()
424
- firecracker_pid = test_microvm .firecracker_pid
425
413
426
414
# Dirty 30MB of pages.
427
415
make_guest_dirty_memory (test_microvm .ssh , amount_mib = 30 )
428
416
429
417
# This call will internally wait for rss to become stable.
430
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
418
+ _ = get_stable_rss_mem ( test_microvm )
431
419
432
420
# Get an initial reading of the stats.
433
421
initial_stats = test_microvm .api .balloon_stats .get ().json ()
@@ -477,17 +465,14 @@ def test_balloon_snapshot(uvm_plain_any, microvm_factory):
477
465
make_guest_dirty_memory (vm .ssh , amount_mib = 60 )
478
466
time .sleep (1 )
479
467
480
- # Get the firecracker pid, and open an ssh connection.
481
- firecracker_pid = vm .firecracker_pid
482
-
483
468
# Check memory usage.
484
- first_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
469
+ first_reading = get_stable_rss_mem ( vm )
485
470
486
471
# Now inflate the balloon with 20MB of pages.
487
472
vm .api .balloon .patch (amount_mib = 20 )
488
473
489
474
# Check memory usage again.
490
- second_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
475
+ second_reading = get_stable_rss_mem ( vm )
491
476
492
477
# There should be a reduction in RSS, but it's inconsistent.
493
478
# We only test that the reduction happens.
@@ -496,28 +481,25 @@ def test_balloon_snapshot(uvm_plain_any, microvm_factory):
496
481
snapshot = vm .snapshot_full ()
497
482
microvm = microvm_factory .build_from_snapshot (snapshot )
498
483
499
- # Get the firecracker from snapshot pid, and open an ssh connection.
500
- firecracker_pid = microvm .firecracker_pid
501
-
502
484
# Wait out the polling interval, then get the updated stats.
503
485
time .sleep (STATS_POLLING_INTERVAL_S * 2 )
504
486
stats_after_snap = microvm .api .balloon_stats .get ().json ()
505
487
506
488
# Check memory usage.
507
- third_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
489
+ third_reading = get_stable_rss_mem ( microvm )
508
490
509
491
# Dirty 60MB of pages.
510
492
make_guest_dirty_memory (microvm .ssh , amount_mib = 60 )
511
493
512
494
# Check memory usage.
513
- fourth_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
495
+ fourth_reading = get_stable_rss_mem ( microvm )
514
496
515
497
assert fourth_reading > third_reading
516
498
517
499
# Inflate the balloon with another 20MB of pages.
518
500
microvm .api .balloon .patch (amount_mib = 40 )
519
501
520
- fifth_reading = get_stable_rss_mem_by_pid ( firecracker_pid )
502
+ fifth_reading = get_stable_rss_mem ( microvm )
521
503
522
504
# There should be a reduction in RSS, but it's inconsistent.
523
505
# We only test that the reduction happens.
@@ -557,15 +539,14 @@ def test_memory_scrub(uvm_plain_any):
557
539
microvm .api .balloon .patch (amount_mib = 60 )
558
540
559
541
# Get the firecracker pid, and open an ssh connection.
560
- firecracker_pid = microvm .firecracker_pid
561
542
562
543
# Wait for the inflate to complete.
563
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
544
+ _ = get_stable_rss_mem ( microvm )
564
545
565
546
# Deflate the balloon completely.
566
547
microvm .api .balloon .patch (amount_mib = 0 )
567
548
568
549
# Wait for the deflate to complete.
569
- _ = get_stable_rss_mem_by_pid ( firecracker_pid )
550
+ _ = get_stable_rss_mem ( microvm )
570
551
571
552
microvm .ssh .check_output ("/usr/local/bin/readmem {} {}" .format (60 , 1 ))
0 commit comments