Skip to content

Commit

Permalink
[decode-syseeprom] Refactor use of swsscommon; Add unit tests (#1444)
Browse files Browse the repository at this point in the history
- Refactor the way swsscommon is used in decode-syseeprom to align with more modern approach
- Add unit tests for DB-related functionality of decode-syseeprom utility
- Align whitespace in tests/mock_tables/state_db.json
  • Loading branch information
jleveque committed Feb 24, 2021
1 parent 787d884 commit 4e27ad7
Show file tree
Hide file tree
Showing 3 changed files with 364 additions and 103 deletions.
58 changes: 20 additions & 38 deletions scripts/decode-syseeprom
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import sys
import sonic_platform
from sonic_platform_base.sonic_eeprom.eeprom_tlvinfo import TlvInfoDecoder
from sonic_py_common import device_info
from swsscommon import swsscommon
from swsscommon.swsscommon import SonicV2Connector
from tabulate import tabulate


Expand Down Expand Up @@ -77,67 +77,49 @@ def print_eeprom_dict(tlv_dict):
def read_eeprom_from_db():
tlv_dict = {}

state_db = swsscommon.DBConnector('STATE_DB', 0)
tbl = swsscommon.Table(state_db, EEPROM_INFO_TABLE)
db = SonicV2Connector(host="127.0.0.1")
db.connect(db.STATE_DB)

status, fvs = tbl.get('State')
status = bool(status)
data = dict(fvs)
if not status or data.get('Initialized', '0') != '1':
initialized = db.get(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, 'State'), 'Initialized')
if initialized != '1':
return None

status, fvs = tbl.get('TlvHeader')
status = bool(status)
if not status:
return None

data = dict(fvs)
tlv_header = db.get_all(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, 'TlvHeader'))
tlv_dict['header'] = {}
tlv_dict['header']['id'] = data.get('Id String', 'N/A')
tlv_dict['header']['version'] = data.get('Version', 'N/A')
tlv_dict['header']['length'] = data.get('Total Length', 'N/A')
tlv_dict['header']['id'] = tlv_header.get('Id String', 'N/A')
tlv_dict['header']['version'] = tlv_header.get('Version', 'N/A')
tlv_dict['header']['length'] = tlv_header.get('Total Length', 'N/A')

tlv_dict['tlv_list'] = []
for tlv_code in range(TlvInfoDecoder._TLV_CODE_PRODUCT_NAME, TlvInfoDecoder._TLV_CODE_SERVICE_TAG + 1):
tlv_code_string = '0x{:02x}'.format(tlv_code)
status, fvs = tbl.get(tlv_code_string)
status = bool(status)
if not status:
continue
tlv_data = db.get_all(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, tlv_code_string))

data = dict(fvs)
tlv = {}
tlv['code'] = tlv_code_string
tlv['name'] = data.get('Name', 'N/A')
tlv['length'] = data.get('Len', 'N/A')
tlv['value'] = data.get('Value', 'N/A')
tlv['name'] = tlv_data.get('Name', 'N/A')
tlv['length'] = tlv_data.get('Len', 'N/A')
tlv['value'] = tlv_data.get('Value', 'N/A')
tlv_dict['tlv_list'].append(tlv)

status, fvs = tbl.get('Checksum')
tlv_dict['checksum_valid'] = dict(fvs).get('Valid', '0') == '1'
checksum_valid = db.get(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, 'Checksum'), 'Valid')
tlv_dict['checksum_valid'] = (checksum_valid == '1')

return tlv_dict


def get_tlv_value_from_db(tlv_code):
state_db = swsscommon.DBConnector('STATE_DB', 0)
tbl = swsscommon.Table(state_db, EEPROM_INFO_TABLE)
db = SonicV2Connector(host="127.0.0.1")
db.connect(db.STATE_DB)

status, fvs = tbl.get('State')
status = bool(status)
data = dict(fvs)
if not status or data.get('Initialized', '0') != '1':
initialized = db.get(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, 'State'), 'Initialized')
if initialized != '1':
print('Failed to read system EEPROM info from DB')
return None

tlv_code_string = '0x{:02x}'.format(tlv_code)
status, fvs = tbl.get(tlv_code_string)
status = bool(status)
if not status:
print('Failed to read system EEPROM info from DB')
return None

return dict(fvs).get('Value')
return db.get(db.STATE_DB, '{}|{}'.format(EEPROM_INFO_TABLE, tlv_code_string), 'Value')


def print_mgmt_mac(use_db=False):
Expand Down
183 changes: 183 additions & 0 deletions tests/decode_syseeprom_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import importlib
import os
import sys
from unittest import mock

import pytest
from click.testing import CliRunner

from .mock_tables import dbconnector

test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
scripts_path = os.path.join(modules_path, 'scripts')
sys.path.insert(0, modules_path)

sys.modules['sonic_platform'] = mock.MagicMock()


decode_syseeprom_path = os.path.join(scripts_path, 'decode-syseeprom')
loader = importlib.machinery.SourceFileLoader('decode-syseeprom', decode_syseeprom_path)
spec = importlib.util.spec_from_loader(loader.name, loader)
decode_syseeprom = importlib.util.module_from_spec(spec)
loader.exec_module(decode_syseeprom)

# Replace swsscommon objects with mocked objects
decode_syseeprom.SonicV2Connector = dbconnector.SonicV2Connector

SAMPLE_TLV_DICT = {
'header': {
'id': 'TlvInfo',
'version': '1',
'length': '170'
},
'tlv_list': [
{
'code': '0x21',
'name': 'Product Name',
'length': '8',
'value': 'S6100-ON'
},
{
'code': '0x22',
'name': 'Part Number',
'length': '6',
'value': '0F6N2R'
},
{
'code': '0x23',
'name': 'Serial Number',
'length': '20',
'value': 'TH0F6N2RCET0007600NG'
},
{
'code': '0x24',
'name': 'Base MAC Address',
'length': '6',
'value': '0C:29:EF:CF:AC:A0'
},
{
'code': '0x25',
'name': 'Manufacture Date',
'length': '19',
'value': '07/07/2020 15:05:34'
},
{
'code': '0x26',
'name': 'Device Version',
'length': '1',
'value': '1'
},
{
'code': '0x27',
'name': 'Label Revision',
'length': '3',
'value': 'A08'
},
{
'code': '0x28',
'name': 'Platform Name',
'length': '26',
'value': 'x86_64-dell_s6100_c2538-r0'
},
{
'code': '0x29',
'name': 'ONIE Version',
'length': '8',
'value': '3.15.1.0'
},
{
'code': '0x2a',
'name': 'MAC Addresses',
'length': '2',
'value': '384'
},
{
'code': '0x2b',
'name': 'Manufacturer',
'length': '5',
'value': 'CET00'
},
{
'code': '0x2c',
'name': 'Manufacture Country',
'length': '2',
'value': 'TH'
},
{
'code': '0x2d',
'name': 'Vendor Name',
'length': '4',
'value': 'DELL'
},
{
'code': '0x2e',
'name': 'Diag Version',
'length': '8',
'value': '3.25.4.1'
},
{
'code': '0x2f',
'name': 'Service Tag',
'length': '7',
'value': 'F3CD9Z2'
}
],
'checksum_valid': True
}

class TestDecodeSyseeprom(object):
def test_print_eeprom_dict(self, capsys):

expected_output = '''\
TlvInfo Header:
Id String: TlvInfo
Version: 1
Total Length: 170
TLV Name Code Len Value
------------------- ------ ----- --------------------------
Product Name 0X21 8 S6100-ON
Part Number 0X22 6 0F6N2R
Serial Number 0X23 20 TH0F6N2RCET0007600NG
Base MAC Address 0X24 6 0C:29:EF:CF:AC:A0
Manufacture Date 0X25 19 07/07/2020 15:05:34
Device Version 0X26 1 1
Label Revision 0X27 3 A08
Platform Name 0X28 26 x86_64-dell_s6100_c2538-r0
ONIE Version 0X29 8 3.15.1.0
MAC Addresses 0X2A 2 384
Manufacturer 0X2B 5 CET00
Manufacture Country 0X2C 2 TH
Vendor Name 0X2D 4 DELL
Diag Version 0X2E 8 3.25.4.1
Service Tag 0X2F 7 F3CD9Z2
(checksum valid)
'''

decode_syseeprom.print_eeprom_dict(SAMPLE_TLV_DICT)
captured = capsys.readouterr()
assert captured.out == expected_output

def test_read_eeprom_from_db(self):
tlv_dict = decode_syseeprom.read_eeprom_from_db()
assert tlv_dict == SAMPLE_TLV_DICT

def test_get_tlv_value_from_db(self):
value = decode_syseeprom.get_tlv_value_from_db(0x28)
assert value == 'x86_64-dell_s6100_c2538-r0'

def test_print_mgmt_mac_db(self, capsys):
decode_syseeprom.print_mgmt_mac(True)
captured = capsys.readouterr()
assert captured.out == '0C:29:EF:CF:AC:A0\n'

def test_print_serial(self, capsys):
decode_syseeprom.print_serial(True)
captured = capsys.readouterr()
assert captured.out == 'TH0F6N2RCET0007600NG\n'

def test_print_model(self, capsys):
decode_syseeprom.print_model(True)
captured = capsys.readouterr()
assert captured.out == 'S6100-ON\n'
Loading

0 comments on commit 4e27ad7

Please sign in to comment.