From b21e2ceb08ac89d08167e1e4cde4f2401091473c Mon Sep 17 00:00:00 2001 From: Xichen96 Date: Tue, 20 Sep 2022 17:24:44 +0800 Subject: [PATCH] [202012][sonic_installer] consider existing swap when setting up swap mem (#2360) * consider swap checking memory in installer Signed-off-by: Xichen Lin * update unit tests for swap allocator Signed-off-by: Xichen Lin Signed-off-by: Xichen Lin Co-authored-by: Jing Kan <672454911@qq.com> --- sonic_installer/main.py | 6 ++-- tests/swap_allocator_test.py | 64 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/sonic_installer/main.py b/sonic_installer/main.py index 7dbddbb9b1..c3a95734d6 100644 --- a/sonic_installer/main.py +++ b/sonic_installer/main.py @@ -338,8 +338,10 @@ def __enter__(self): meminfo = self.read_from_meminfo() mem_total_in_bytes = meminfo["MemTotal"] * SWAPAllocator.KiB_TO_BYTES_FACTOR mem_avail_in_bytes = meminfo["MemAvailable"] * SWAPAllocator.KiB_TO_BYTES_FACTOR - if (mem_total_in_bytes < self.total_mem_threshold * SWAPAllocator.MiB_TO_BYTES_FACTOR - or mem_avail_in_bytes < self.available_mem_threshold * SWAPAllocator.MiB_TO_BYTES_FACTOR): + swap_total_in_bytes = meminfo["SwapTotal"] * SWAPAllocator.KiB_TO_BYTES_FACTOR + swap_free_in_bytes = meminfo["SwapFree"] * SWAPAllocator.KiB_TO_BYTES_FACTOR + if (mem_total_in_bytes + swap_total_in_bytes < self.total_mem_threshold * SWAPAllocator.MiB_TO_BYTES_FACTOR + or mem_avail_in_bytes + swap_free_in_bytes < self.available_mem_threshold * SWAPAllocator.MiB_TO_BYTES_FACTOR): echo_and_log("Setup SWAP memory") swapfile = SWAPAllocator.SWAP_FILE_PATH if os.path.exists(swapfile): diff --git a/tests/swap_allocator_test.py b/tests/swap_allocator_test.py index 033b215dd2..960d4e8caf 100644 --- a/tests/swap_allocator_test.py +++ b/tests/swap_allocator_test.py @@ -17,6 +17,8 @@ def test_read_from_meminfo(self): proc_meminfo_lines = [ "MemTotal: 32859496 kB", "MemFree: 16275512 kB", + "SwapTotal: 2000000 kB", + "SwapFree: 1000000 kB", "HugePages_Total: 0", "HugePages_Free: 0", ] @@ -24,6 +26,8 @@ def test_read_from_meminfo(self): read_meminfo_expected_return = { "MemTotal": 32859496, "MemFree": 16275512, + "SwapTotal": 2000000, + "SwapFree": 1000000, "HugePages_Total": 0, "HugePages_Free": 0 } @@ -113,6 +117,8 @@ def test_swap_allocator_context_enter_allocate_true_insufficient_total_memory(se mock_meminfo.return_value = { "MemTotal": 2000000, "MemAvailable": 1900000, + "SwapTotal": 0, + "SwapFree": 0, } mock_exists.return_value = False @@ -135,6 +141,56 @@ def test_swap_allocator_context_enter_allocate_true_insufficient_available_memor mock_meminfo.return_value = { "MemTotal": 3000000, "MemAvailable": 1000000, + "SwapTotal": 0, + "SwapFree": 0, + } + mock_exists.return_value = False + + swap_allocator = SWAPAllocator(allocate=True) + try: + swap_allocator.__enter__() + except Exception as detail: + pytest.fail("SWAPAllocator context manager should not raise exception %s" % repr(detail)) + mock_setup.assert_called_once() + mock_remove.assert_not_called() + assert swap_allocator.is_allocated is True + + def test_swap_allocator_context_enter_allocate_true_insufficient_total_memory_plus_swap(self): + with mock.patch("sonic_installer.main.SWAPAllocator.get_disk_freespace") as mock_disk_free, \ + mock.patch("sonic_installer.main.SWAPAllocator.read_from_meminfo") as mock_meminfo, \ + mock.patch("sonic_installer.main.SWAPAllocator.setup_swapmem") as mock_setup, \ + mock.patch("sonic_installer.main.SWAPAllocator.remove_swapmem") as mock_remove, \ + mock.patch("os.path.exists") as mock_exists: + mock_disk_free.return_value = 10 * 1024 * 1024 * 1024 + mock_meminfo.return_value = { + "MemTotal": 1000000, + "MemAvailable": 900000, + "SwapTotal": 1000000, + "SwapFree": 1000000, + } + mock_exists.return_value = False + + swap_allocator = SWAPAllocator(allocate=True) + try: + swap_allocator.__enter__() + except Exception as detail: + pytest.fail("SWAPAllocator context manager should not raise exception %s" % repr(detail)) + mock_setup.assert_called_once() + mock_remove.assert_not_called() + assert swap_allocator.is_allocated is True + + def test_swap_allocator_context_enter_allocate_true_insufficient_available_memory_plus_swap(self): + with mock.patch("sonic_installer.main.SWAPAllocator.get_disk_freespace") as mock_disk_free, \ + mock.patch("sonic_installer.main.SWAPAllocator.read_from_meminfo") as mock_meminfo, \ + mock.patch("sonic_installer.main.SWAPAllocator.setup_swapmem") as mock_setup, \ + mock.patch("sonic_installer.main.SWAPAllocator.remove_swapmem") as mock_remove, \ + mock.patch("os.path.exists") as mock_exists: + mock_disk_free.return_value = 10 * 1024 * 1024 * 1024 + mock_meminfo.return_value = { + "MemTotal": 2000000, + "MemAvailable": 500000, + "SwapTotal": 1000000, + "SwapFree": 500000, } mock_exists.return_value = False @@ -157,6 +213,8 @@ def test_swap_allocator_context_enter_allocate_true_insufficient_disk_space(self mock_meminfo.return_value = { "MemTotal": 32859496, "MemAvailable": 16275512, + "SwapTotal": 0, + "SwapFree": 0, } mock_exists.return_value = False @@ -179,6 +237,8 @@ def test_swap_allocator_context_enter_allocate_true_swapfile_present(self): mock_meminfo.return_value = { "MemTotal": 32859496, "MemAvailable": 1000000, + "SwapTotal": 0, + "SwapFree": 0, } mock_exists.return_value = True @@ -201,6 +261,8 @@ def test_swap_allocator_context_enter_setup_error(self): mock_meminfo.return_value = { "MemTotal": 32859496, "MemAvailable": 1000000, + "SwapTotal": 0, + "SwapFree": 0, } mock_exists.return_value = False expected_err_str = "Pseudo Error" @@ -225,6 +287,8 @@ def test_swap_allocator_context_enter_allocate_false(self): mock_meminfo.return_value = { "MemTotal": 32859496, "MemAvailable": 1000000, + "SwapTotal": 0, + "SwapFree": 0, } mock_exists.return_value = False