Skip to content

Commit 4910298

Browse files
authored
[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 <[email protected]> * Removed UT since libswsscommom dep is missing in <=202205 Signed-off-by: Vivek Reddy <[email protected]> Signed-off-by: Vivek Reddy Karri <[email protected]> Signed-off-by: Vivek Reddy <[email protected]>
1 parent e2cade3 commit 4910298

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed

src/sonic-py-common/sonic_py_common/device_info.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
CHASSIS_INFO_MODEL_FIELD = 'model'
4141
CHASSIS_INFO_REV_FIELD = 'revision'
4242

43+
# Cacheable Objects
44+
sonic_ver_info = {}
45+
hw_info_dict = {}
46+
4347
def get_localhost_info(field, config_db=None):
4448
try:
4549
# TODO: enforce caller to provide config_db explicitly and remove its default value
@@ -334,14 +338,17 @@ def get_sonic_version_info():
334338
if not os.path.isfile(SONIC_VERSION_YAML_PATH):
335339
return None
336340

337-
data = {}
341+
global sonic_ver_info
342+
if sonic_ver_info:
343+
return sonic_ver_info
344+
338345
with open(SONIC_VERSION_YAML_PATH) as stream:
339346
if yaml.__version__ >= "5.1":
340-
data = yaml.full_load(stream)
347+
sonic_ver_info = yaml.full_load(stream)
341348
else:
342-
data = yaml.load(stream)
349+
sonic_ver_info = yaml.load(stream)
343350

344-
return data
351+
return sonic_ver_info
345352

346353
def get_sonic_version_file():
347354
if not os.path.isfile(SONIC_VERSION_YAML_PATH):
@@ -355,9 +362,12 @@ def get_platform_info(config_db=None):
355362
"""
356363
This function is used to get the HW info helper function
357364
"""
358-
from .multi_asic import get_num_asics
365+
global hw_info_dict
359366

360-
hw_info_dict = {}
367+
if hw_info_dict:
368+
return hw_info_dict
369+
370+
from .multi_asic import get_num_asics
361371

362372
version_info = get_sonic_version_info()
363373

src/sonic-py-common/tests/device_info_test.py

+58
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,32 @@
5252
'onie_kernel_version': '4.10.11'
5353
}
5454

55+
SONIC_VERISON_YML = """\
56+
---
57+
build_version: 'test_branch.1-a8fbac59d'
58+
debian_version: '11.4'
59+
kernel_version: '5.10.0-12-2-amd64'
60+
asic_type: mellanox
61+
asic_subtype: 'mellanox'
62+
commit_id: 'a8fbac59d'
63+
branch: 'test_branch'
64+
release: 'master'
65+
libswsscommon: 1.0.0
66+
sonic_utilities: 1.2"""
67+
68+
SONIC_VERISON_YML_RESULT = {
69+
'build_version': 'test_branch.1-a8fbac59d',
70+
'debian_version': '11.4',
71+
'kernel_version': '5.10.0-12-2-amd64',
72+
'asic_type': 'mellanox',
73+
'asic_subtype': 'mellanox',
74+
'commit_id': 'a8fbac59d',
75+
'branch': 'test_branch',
76+
'release': 'master',
77+
'libswsscommon': '1.0.0',
78+
'sonic_utilities': 1.2
79+
}
80+
5581
class TestDeviceInfo(object):
5682
@pytest.fixture(scope="class", autouse=True)
5783
def sanitize_environment(self):
@@ -83,6 +109,38 @@ def test_get_chassis_info(self):
83109
"revision": SonicV2Connector.TEST_REV}
84110
assert result == truth
85111

112+
@mock.patch("os.path.isfile")
113+
def test_get_sonic_version(self, mock_isfile):
114+
mock_isfile.return_value = True
115+
open_mocked = mock.mock_open(read_data=SONIC_VERISON_YML)
116+
with mock.patch("{}.open".format(BUILTINS), open_mocked):
117+
for _ in range(0,5):
118+
assert device_info.get_sonic_version_info() == SONIC_VERISON_YML_RESULT
119+
# Assert the file was read only once
120+
open_mocked.assert_called_once_with(device_info.SONIC_VERSION_YAML_PATH)
121+
122+
@mock.patch("sonic_py_common.device_info.get_platform_info")
123+
def test_is_chassis(self, mock_platform_info):
124+
mock_platform_info.return_value = {"switch_type": "npu"}
125+
assert device_info.is_chassis() == False
126+
assert device_info.is_voq_chassis() == False
127+
assert device_info.is_packet_chassis() == False
128+
129+
mock_platform_info.return_value = {"switch_type": "voq"}
130+
assert device_info.is_voq_chassis() == True
131+
assert device_info.is_packet_chassis() == False
132+
assert device_info.is_chassis() == True
133+
134+
mock_platform_info.return_value = {"switch_type": "chassis-packet"}
135+
assert device_info.is_voq_chassis() == False
136+
assert device_info.is_packet_chassis() == True
137+
assert device_info.is_chassis() == True
138+
139+
mock_platform_info.return_value = {}
140+
assert device_info.is_voq_chassis() == False
141+
assert device_info.is_packet_chassis() == False
142+
assert device_info.is_chassis() == False
143+
86144
@classmethod
87145
def teardown_class(cls):
88146
print("TEARDOWN")

0 commit comments

Comments
 (0)