[202205] [sonic_py_common] Cache Static Information in device_info to speed up CLI response (#11866)

* [sonic_py_common] Cache Static Information in device_info to speed up CLI response (#11696)

- Why I did it
Profiled the execution for the following cmd intfutil -c status

- How I did it
Cached the following information:
1. get_sonic_version_info()
2. get_platform_info()
None of the API exposed to the user libraries (for eg: sonic-utilities) has been modified
These methods involve reading text files or from redis. Thus, caching helped to improve the execution time

- How to verify it
Added UT's.
Verified on the device

Signed-off-by: Vivek Reddy Karri <vkarri@nvidia.com>

* Removed UT since libswsscommom dep is missing in <=202205

Signed-off-by: Vivek Reddy <vkarri@nvidia.com>

Signed-off-by: Vivek Reddy Karri <vkarri@nvidia.com>
Signed-off-by: Vivek Reddy <vkarri@nvidia.com>
This commit is contained in:
Vivek 2022-08-29 08:57:45 -07:00 committed by GitHub
parent e2cade3ca0
commit 4910298f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 6 deletions

View File

@ -40,6 +40,10 @@ CHASSIS_INFO_SERIAL_FIELD = 'serial'
CHASSIS_INFO_MODEL_FIELD = 'model'
CHASSIS_INFO_REV_FIELD = 'revision'
# Cacheable Objects
sonic_ver_info = {}
hw_info_dict = {}
def get_localhost_info(field, config_db=None):
try:
# TODO: enforce caller to provide config_db explicitly and remove its default value
@ -334,14 +338,17 @@ def get_sonic_version_info():
if not os.path.isfile(SONIC_VERSION_YAML_PATH):
return None
data = {}
global sonic_ver_info
if sonic_ver_info:
return sonic_ver_info
with open(SONIC_VERSION_YAML_PATH) as stream:
if yaml.__version__ >= "5.1":
data = yaml.full_load(stream)
sonic_ver_info = yaml.full_load(stream)
else:
data = yaml.load(stream)
sonic_ver_info = yaml.load(stream)
return data
return sonic_ver_info
def get_sonic_version_file():
if not os.path.isfile(SONIC_VERSION_YAML_PATH):
@ -355,9 +362,12 @@ def get_platform_info(config_db=None):
"""
This function is used to get the HW info helper function
"""
from .multi_asic import get_num_asics
global hw_info_dict
hw_info_dict = {}
if hw_info_dict:
return hw_info_dict
from .multi_asic import get_num_asics
version_info = get_sonic_version_info()

View File

@ -52,6 +52,32 @@ EXPECTED_GET_MACHINE_INFO_RESULT = {
'onie_kernel_version': '4.10.11'
}
SONIC_VERISON_YML = """\
---
build_version: 'test_branch.1-a8fbac59d'
debian_version: '11.4'
kernel_version: '5.10.0-12-2-amd64'
asic_type: mellanox
asic_subtype: 'mellanox'
commit_id: 'a8fbac59d'
branch: 'test_branch'
release: 'master'
libswsscommon: 1.0.0
sonic_utilities: 1.2"""
SONIC_VERISON_YML_RESULT = {
'build_version': 'test_branch.1-a8fbac59d',
'debian_version': '11.4',
'kernel_version': '5.10.0-12-2-amd64',
'asic_type': 'mellanox',
'asic_subtype': 'mellanox',
'commit_id': 'a8fbac59d',
'branch': 'test_branch',
'release': 'master',
'libswsscommon': '1.0.0',
'sonic_utilities': 1.2
}
class TestDeviceInfo(object):
@pytest.fixture(scope="class", autouse=True)
def sanitize_environment(self):
@ -83,6 +109,38 @@ class TestDeviceInfo(object):
"revision": SonicV2Connector.TEST_REV}
assert result == truth
@mock.patch("os.path.isfile")
def test_get_sonic_version(self, mock_isfile):
mock_isfile.return_value = True
open_mocked = mock.mock_open(read_data=SONIC_VERISON_YML)
with mock.patch("{}.open".format(BUILTINS), open_mocked):
for _ in range(0,5):
assert device_info.get_sonic_version_info() == SONIC_VERISON_YML_RESULT
# Assert the file was read only once
open_mocked.assert_called_once_with(device_info.SONIC_VERSION_YAML_PATH)
@mock.patch("sonic_py_common.device_info.get_platform_info")
def test_is_chassis(self, mock_platform_info):
mock_platform_info.return_value = {"switch_type": "npu"}
assert device_info.is_chassis() == False
assert device_info.is_voq_chassis() == False
assert device_info.is_packet_chassis() == False
mock_platform_info.return_value = {"switch_type": "voq"}
assert device_info.is_voq_chassis() == True
assert device_info.is_packet_chassis() == False
assert device_info.is_chassis() == True
mock_platform_info.return_value = {"switch_type": "chassis-packet"}
assert device_info.is_voq_chassis() == False
assert device_info.is_packet_chassis() == True
assert device_info.is_chassis() == True
mock_platform_info.return_value = {}
assert device_info.is_voq_chassis() == False
assert device_info.is_packet_chassis() == False
assert device_info.is_chassis() == False
@classmethod
def teardown_class(cls):
print("TEARDOWN")