From 030293c12875fd21c034b06e24e6d9ad69d9a450 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 8 Apr 2021 10:24:31 -0700 Subject: [PATCH] Use 'importlib' module in lieu of deprecated 'imp' module (#1450) Migrate from using the `imp` module to using the `importlib` module. As of Python 3, the `imp` module has been deprecated in favor of the `importlib` module. Place logic in a new function, `load_module_from_source()` in a new file, `utilities_common/general.py` Also fix some formatting --- config/config_mgmt.py | 39 +++++----- pfcwd/main.py | 6 +- tests/aclshow_test.py | 99 ++++++++++++++++---------- tests/buffer_test.py | 1 - tests/config_dpb_test.py | 21 +++--- tests/config_mgmt_test.py | 114 +++++++++++++++++------------- tests/config_test.py | 10 +-- tests/crm_test.py | 4 +- tests/decode_syseeprom_test.py | 7 +- tests/feature_test.py | 12 ++-- tests/neighbor_advertiser_test.py | 15 ++-- tests/pfcstat_test.py | 1 - tests/pfcwd_test.py | 4 +- tests/port2alias_test.py | 9 ++- tests/psushow_test.py | 7 +- tests/watermarkstat_test.py | 1 - utilities_common/general.py | 17 +++++ utilities_common/util_base.py | 3 +- 18 files changed, 206 insertions(+), 164 deletions(-) create mode 100644 utilities_common/general.py diff --git a/config/config_mgmt.py b/config/config_mgmt.py index 194c8aefc981..cc64b35d971c 100644 --- a/config/config_mgmt.py +++ b/config/config_mgmt.py @@ -2,28 +2,21 @@ config_mgmt.py provides classes for configuration validation and for Dynamic Port Breakout. ''' -try: - import re - import syslog +import re +import syslog +from json import load +from sys import flags +from time import sleep as tsleep - from json import load - from time import sleep as tsleep - from imp import load_source - from jsondiff import diff - from sys import flags +import sonic_yang +from jsondiff import diff +from swsssdk import port_util +from swsscommon.swsscommon import SonicV2Connector, ConfigDBConnector +from utilities_common.general import load_module_from_source - # SONiC specific imports - import sonic_yang - from swsssdk import port_util - from swsscommon.swsscommon import SonicV2Connector, ConfigDBConnector - # Using load_source to 'import /usr/local/bin/sonic-cfggen as sonic_cfggen' - # since /usr/local/bin/sonic-cfggen does not have .py extension. - load_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen') - from sonic_cfggen import deep_update, FormatConverter - -except ImportError as e: - raise ImportError("%s - required module not found" % str(e)) +# Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension. +sonic_cfggen = load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen') # Globals YANG_DIR = "/usr/local/yang-models" @@ -193,8 +186,8 @@ def readConfigDB(self): data = dict() configdb = ConfigDBConnector() configdb.connect() - deep_update(data, FormatConverter.db_to_output(configdb.get_config())) - self.configdbJsonIn = FormatConverter.to_serialized(data) + sonic_cfggen.deep_update(data, sonic_cfggen.FormatConverter.db_to_output(configdb.get_config())) + self.configdbJsonIn = sonic_cfggen.FormatConverter.to_serialized(data) self.sysLog(syslog.LOG_DEBUG, 'Reading Input from ConfigDB {}'.\ format(self.configdbJsonIn)) @@ -214,9 +207,9 @@ def writeConfigDB(self, jDiff): data = dict() configdb = ConfigDBConnector() configdb.connect(False) - deep_update(data, FormatConverter.to_deserialized(jDiff)) + sonic_cfggen.deep_update(data, sonic_cfggen.FormatConverter.to_deserialized(jDiff)) self.sysLog(msg="Write in DB: {}".format(data)) - configdb.mod_config(FormatConverter.output_to_db(data)) + configdb.mod_config(sonic_cfggen.FormatConverter.output_to_db(data)) return diff --git a/pfcwd/main.py b/pfcwd/main.py index 9b038316ca78..1f8ec2293e4b 100644 --- a/pfcwd/main.py +++ b/pfcwd/main.py @@ -1,11 +1,9 @@ +import importlib import os -import imp import sys import click - import utilities_common.cli as clicommon - from natsort import natsorted from sonic_py_common.multi_asic import get_external_ports from tabulate import tabulate @@ -27,7 +25,7 @@ import mock_tables.dbconnector if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic": import mock_tables.mock_multi_asic - imp.reload(mock_tables.mock_multi_asic) + importlib.reload(mock_tables.mock_multi_asic) mock_tables.dbconnector.load_namespace_config() except KeyError: diff --git a/tests/aclshow_test.py b/tests/aclshow_test.py index b2371e972398..e41d56b9eb0c 100644 --- a/tests/aclshow_test.py +++ b/tests/aclshow_test.py @@ -1,24 +1,26 @@ -import sys +import json import os -from imp import load_source +import sys from io import StringIO from unittest import mock +from utilities_common.general import load_module_from_source 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) -load_source('aclshow', scripts_path+'/aclshow') -from aclshow import * +# Load the file under test +aclshow_path = os.path.join(scripts_path, 'aclshow') +aclshow = load_module_from_source('aclshow', aclshow_path) from .mock_tables import dbconnector # Expected output for aclshow -default_output = ''+ \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +default_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ------------ ------------ ------ --------------- ------------- RULE_1 DATAACL 9999 101 100 RULE_2 DATAACL 9998 201 200 @@ -32,8 +34,8 @@ """ # Expected output for aclshow -a -all_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +all_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ------------ ------------ ------ --------------- ------------- RULE_1 DATAACL 9999 101 100 RULE_2 DATAACL 9998 201 200 @@ -49,35 +51,35 @@ """ # Expected output for aclshow -r RULE_1 -t DATAACL -rule1_dataacl_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +rule1_dataacl_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ----------- ------------ ------ --------------- ------------- RULE_1 DATAACL 9999 101 100 """ # Expected output for aclshow -r RULE_1 -t DATAACL -rule10_dataacl_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +rule10_dataacl_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ----------- ------------ ------ --------------- ------------- RULE_10 DATAACL 9989 1001 1000 """ # Expected output for aclshow -a -r RULE_05 -rule05_all_output = ''+ \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +rule05_all_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ----------- ------------ ------ --------------- ------------- RULE_05 DATAACL 9995 0 0 """ # Expected output for aclshow -r RULE_0 -rule0_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +rule0_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ----------- ------------ ------ --------------- ------------- """ # Expected output for aclshow -r RULE_4,RULE_6 -vv -rule4_rule6_verbose_output = '' + \ -"""Reading ACL info... +rule4_rule6_verbose_output = """\ +Reading ACL info... Total number of ACL Tables: 8 Total number of ACL Rules: 11 @@ -88,15 +90,15 @@ """ # Expected output for aclshow -t EVERFLOW -everflow_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +everflow_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ----------- ------------ ------ --------------- ------------- RULE_6 EVERFLOW 9994 601 600 """ # Expected output for aclshow -t DATAACL -dataacl_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +dataacl_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ------------ ------------ ------ --------------- ------------- RULE_1 DATAACL 9999 101 100 RULE_2 DATAACL 9998 201 200 @@ -113,8 +115,8 @@ # Expected output for # aclshow -a -c ; aclshow -a -all_after_clear_output = '' + \ -"""RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT +all_after_clear_output = """\ +RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT ------------ ------------ ------ --------------- ------------- RULE_1 DATAACL 9999 0 0 RULE_2 DATAACL 9998 0 0 @@ -129,6 +131,7 @@ RULE_08 EVERFLOW 9992 0 0 """ + class Aclshow(): def __init__(self, *args, **kwargs): """ @@ -146,8 +149,8 @@ def nullify_counters(self): This method is used to empty dumped counters if exist in /tmp/.counters_acl.p (by default). """ - if os.path.isfile(COUNTER_POSITION): - with open(COUNTER_POSITION, 'w') as fp: + if os.path.isfile(aclshow.COUNTER_POSITION): + with open(aclshow.COUNTER_POSITION, 'w') as fp: json.dump([], fp) def runTest(self): @@ -155,10 +158,10 @@ def runTest(self): This method invokes main() from aclshow utility (parametrized by argparse) parametrized by mock argparse. """ - @mock.patch('argparse.ArgumentParser.parse_args', return_value = argparse.Namespace(**self.kwargs)) - def run(mock_args): - main() - run() + with mock.patch.object(aclshow.argparse.ArgumentParser, + 'parse_args', + return_value=aclshow.argparse.Namespace(**self.kwargs)): + aclshow.main() def setUp(self): if self.nullify_on_start: @@ -173,56 +176,78 @@ def tearDown(self): sys.stdout = self.old_stdout # aclshow + + def test_default(): - test = Aclshow(all = None, clear = None, rules = None, tables = None, verbose = None) + test = Aclshow(all=None, clear=None, rules=None, tables=None, verbose=None) assert test.result.getvalue() == default_output # aclshow -a + + def test_all(): - test = Aclshow(all = True, clear = None, rules = None, tables = None, verbose = None) + test = Aclshow(all=True, clear=None, rules=None, tables=None, verbose=None) assert test.result.getvalue() == all_output # aclshow -r RULE_1 -t DATAACL + + def test_rule1_dataacl(): - test = Aclshow(all = None, clear = None, rules = 'RULE_1', tables = 'DATAACL', verbose = None) + test = Aclshow(all=None, clear=None, rules='RULE_1', tables='DATAACL', verbose=None) assert test.result.getvalue() == rule1_dataacl_output # aclshow -a -r RULE_05 + + def test_rule05_all(): - test = Aclshow(all = True, clear = None, rules = 'RULE_05', tables = None, verbose = None) + test = Aclshow(all=True, clear=None, rules='RULE_05', tables=None, verbose=None) assert test.result.getvalue() == rule05_all_output # aclshow -r RULE_0 + + def test_rule0(): - test = Aclshow(all = None, clear = None, rules = 'RULE_0', tables = None, verbose = None) + test = Aclshow(all=None, clear=None, rules='RULE_0', tables=None, verbose=None) assert test.result.getvalue() == rule0_output # aclshow -r RULE_10 -t DATAACL + + def test_rule10_lowercase_priority(): - test = Aclshow(all = None, clear = None, rules = 'RULE_10', tables = 'DATAACL', verbose = None) + test = Aclshow(all=None, clear=None, rules='RULE_10', tables='DATAACL', verbose=None) assert test.result.getvalue() == rule10_dataacl_output # aclshow -r RULE_4,RULE_6 -vv + + def test_rule4_rule6_verbose(): - test = Aclshow(all = None, clear = None, rules = 'RULE_4,RULE_6', tables = None, verbose = True) + test = Aclshow(all=None, clear=None, rules='RULE_4,RULE_6', tables=None, verbose=True) assert test.result.getvalue() == rule4_rule6_verbose_output # aclshow -t EVERFLOW + + def test_everflow(): test = Aclshow(all=None, clear=None, rules=None, tables='EVERFLOW', verbose=None) assert test.result.getvalue() == everflow_output # aclshow -t DATAACL + + def test_dataacl(): test = Aclshow(all=None, clear=None, rules=None, tables='DATAACL', verbose=None) assert test.result.getvalue() == dataacl_output # aclshow -c + + def test_clear(): test = Aclshow(all=None, clear=True, rules=None, tables=None, verbose=None) assert test.result.getvalue() == clear_output # aclshow -a -c ; aclshow -a + + def test_all_after_clear(): nullify_on_start, nullify_on_exit = True, False test = Aclshow(nullify_on_start, nullify_on_exit, all=True, clear=True, rules=None, tables=None, verbose=None) diff --git a/tests/buffer_test.py b/tests/buffer_test.py index fbbf2ba3bdd1..30abfad8ebd1 100644 --- a/tests/buffer_test.py +++ b/tests/buffer_test.py @@ -1,4 +1,3 @@ -import imp import os import sys from click.testing import CliRunner diff --git a/tests/config_dpb_test.py b/tests/config_dpb_test.py index e347538bcf18..1d58e90c6753 100644 --- a/tests/config_dpb_test.py +++ b/tests/config_dpb_test.py @@ -1,21 +1,22 @@ import json import os import re -from imp import load_source from unittest import mock import pytest from click.testing import CliRunner from utilities_common.db import Db +from utilities_common.general import load_module_from_source import config.main as config -load_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen') -from sonic_cfggen import deep_update, FormatConverter +# Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension. +sonic_cfggen = load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen') + +# Import config_mgmt.py +config_mgmt_py_path = os.path.join(os.path.dirname(__file__), '..', 'config', 'config_mgmt.py') +config_mgmt = load_module_from_source('config_mgmt', config_mgmt_py_path) -load_source('config_mgmt', \ - os.path.join(os.path.dirname(__file__), '..', 'config', 'config_mgmt.py')) -import config_mgmt # Sample platform.json for Test BRKOUT_CFG_FILE_JSON = { @@ -137,14 +138,14 @@ def mock_func(breakout_cfg_file, sonic_db): def write_config_db(cfgdb, config): data = dict() - deep_update(data, FormatConverter.to_deserialized(config)) - cfgdb.mod_config(FormatConverter.output_to_db(data)) + sonic_cfggen.deep_update(data, sonic_cfggen.FormatConverter.to_deserialized(config)) + cfgdb.mod_config(sonic_cfggen.FormatConverter.output_to_db(data)) return def read_config_db(cfgdb): data = dict() - deep_update(data, FormatConverter.db_to_output(cfgdb.get_config())) - return FormatConverter.to_serialized(data) + sonic_cfggen.deep_update(data, sonic_cfggen.FormatConverter.db_to_output(cfgdb.get_config())) + return sonic_cfggen.FormatConverter.to_serialized(data) def writeJson(d, file): with open(file, 'w') as f: diff --git a/tests/config_mgmt_test.py b/tests/config_mgmt_test.py index adeca71d4ed2..39e387099046 100644 --- a/tests/config_mgmt_test.py +++ b/tests/config_mgmt_test.py @@ -1,15 +1,15 @@ -import imp import os import sys +from json import dump +from copy import deepcopy from unittest import mock, TestCase -# import file under test i.e. config_mgmt.py -imp.load_source('config_mgmt', \ - os.path.join(os.path.dirname(__file__), '..', 'config', 'config_mgmt.py')) -import config_mgmt +from utilities_common.general import load_module_from_source + +# Import file under test i.e., config_mgmt.py +config_mgmt_py_path = os.path.join(os.path.dirname(__file__), '..', 'config', 'config_mgmt.py') +config_mgmt = load_module_from_source('config_mgmt', config_mgmt_py_path) -from json import dump -from copy import deepcopy class TestConfigMgmt(TestCase): ''' @@ -41,15 +41,15 @@ def test_search_keys(self): curConfig = deepcopy(configDbJson) self.writeJson(curConfig, config_mgmt.CONFIG_DB_JSON_FILE) cmdpb = config_mgmt.ConfigMgmtDPB(source=config_mgmt.CONFIG_DB_JSON_FILE) - out = cmdpb.configWithKeys(portBreakOutConfigDbJson, \ - ["Ethernet8","Ethernet9"]) + out = cmdpb.configWithKeys(portBreakOutConfigDbJson, + ["Ethernet8", "Ethernet9"]) assert "VLAN" not in out assert "INTERFACE" not in out for k in out['ACL_TABLE']: # only ports must be chosen len(out['ACL_TABLE'][k]) == 1 - out = cmdpb.configWithKeys(portBreakOutConfigDbJson, \ - ["Ethernet10","Ethernet11"]) + out = cmdpb.configWithKeys(portBreakOutConfigDbJson, + ["Ethernet10", "Ethernet11"]) assert "INTERFACE" in out for k in out['ACL_TABLE']: # only ports must be chosen @@ -58,13 +58,13 @@ def test_search_keys(self): def test_break_out(self): # prepare default config - self.writeJson(portBreakOutConfigDbJson, \ - config_mgmt.DEFAULT_CONFIG_DB_JSON_FILE) + self.writeJson(portBreakOutConfigDbJson, + config_mgmt.DEFAULT_CONFIG_DB_JSON_FILE) # prepare config dj json to start with curConfig = deepcopy(configDbJson) - #Ethernet8: start from 4x25G-->2x50G with -f -l + # Ethernet8: start from 4x25G-->2x50G with -f -l self.dpb_port8_4x25G_2x50G_f_l(curConfig) - #Ethernet8: move from 2x50G-->1x100G without force, list deps + # Ethernet8: move from 2x50G-->1x100G without force, list deps self.dpb_port8_2x50G_1x100G(curConfig) # Ethernet8: move from 2x50G-->1x100G with force, where deps exists self.dpb_port8_2x50G_1x100G_f(curConfig) @@ -136,28 +136,39 @@ def generate_args(self, portIdx, laneIdx, curMode, newMode): ''' # default params pre = "Ethernet" - laneMap = {"4x25G": [1,1,1,1], "2x50G": [2,2], "1x100G":[4], \ - "1x50G(2)+2x25G(2)":[2,1,1], "2x25G(2)+1x50G(2)":[1,1,2]} + laneMap = {"4x25G": [1, 1, 1, 1], "2x50G": [2, 2], "1x100G": [4], + "1x50G(2)+2x25G(2)": [2, 1, 1], "2x25G(2)+1x50G(2)": [1, 1, 2]} laneSpeed = 25000 # generate dPorts - l = list(laneMap[curMode]); l.insert(0, 0); id = portIdx; dPorts = list() + l = list(laneMap[curMode]) + l.insert(0, 0) + id = portIdx + dPorts = list() for i in l[:-1]: id = id + i portName = portName = "{}{}".format(pre, id) dPorts.append(portName) # generate aPorts - l = list(laneMap[newMode]); l.insert(0, 0); id = portIdx; aPorts = list() + l = list(laneMap[newMode]) + l.insert(0, 0) + id = portIdx + aPorts = list() for i in l[:-1]: id = id + i portName = portName = "{}{}".format(pre, id) aPorts.append(portName) # generate pJson - l = laneMap[newMode]; pJson = {"PORT": {}}; li = laneIdx; pi = 0 + l = laneMap[newMode] + pJson = {"PORT": {}} + li = laneIdx + pi = 0 for i in l: speed = laneSpeed*i - lanes = [str(li+j) for j in range(i)]; lanes = ','.join(lanes) + lanes = [str(li+j) for j in range(i)] + lanes = ','.join(lanes) pJson['PORT'][aPorts[pi]] = {"speed": str(speed), "lanes": str(lanes)} - li = li+i; pi = pi + 1 + li = li+i + pi = pi + 1 return dPorts, pJson def updateConfig(self, conf, uconf): @@ -256,10 +267,10 @@ def dpb_port8_1x100G_1x50G_2x25G_f_l(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='1x100G', newMode='1x50G(2)+2x25G(2)') + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='1x100G', newMode='1x50G(2)+2x25G(2)') deps, ret = cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, - force=True, loadDefConfig=True) + force=True, loadDefConfig=True) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'PORT': { @@ -322,10 +333,10 @@ def dpb_port8_4x25G_1x100G_f(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='4x25G', newMode='1x100G') + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='4x25G', newMode='1x100G') deps, ret = cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, - force=False, loadDefConfig=False) + force=False, loadDefConfig=False) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'PORT': { @@ -352,10 +363,10 @@ def dpb_port8_1x100G_4x25G(self, curConfig): assert for success and failure. ''' cmdpb = self.config_mgmt_dpb(curConfig) - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='1x100G', newMode='4x25G') + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='1x100G', newMode='4x25G') deps, ret = cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, - force=False, loadDefConfig=False) + force=False, loadDefConfig=False) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'PORT': { @@ -380,10 +391,10 @@ def dpb_port8_2x50G_1x100G_f(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='2x50G', newMode='1x100G') + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='2x50G', newMode='1x100G') deps, ret = cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, - force=True, loadDefConfig=False) + force=True, loadDefConfig=False) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'ACL_TABLE': { @@ -416,10 +427,10 @@ def dpb_port8_2x50G_1x100G(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='2x50G', newMode='1x100G') + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='2x50G', newMode='1x100G') deps, ret = cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, - force=False, loadDefConfig=False) + force=False, loadDefConfig=False) # Expected Result assert ret == False and len(deps) == 3 assert cmdpb.writeConfigDB.call_count == 0 @@ -438,10 +449,10 @@ def dpb_port8_4x25G_2x50G_f_l(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, \ - curMode='4x25G', newMode='2x50G') - cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, force=True, \ - loadDefConfig=True) + dPorts, pJson = self.generate_args(portIdx=8, laneIdx=73, + curMode='4x25G', newMode='2x50G') + cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, force=True, + loadDefConfig=True) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'ACL_TABLE': { @@ -504,10 +515,10 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): ''' cmdpb = self.config_mgmt_dpb(curConfig) # create ARGS - dPorts, pJson = self.generate_args(portIdx=4, laneIdx=69, \ - curMode='4x25G', newMode='2x50G') - cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, force=True, \ - loadDefConfig=True) + dPorts, pJson = self.generate_args(portIdx=4, laneIdx=69, + curMode='4x25G', newMode='2x50G') + cmdpb.breakOutPort(delPorts=dPorts, portJson=pJson, force=True, + loadDefConfig=True) # Expected Result delConfig and addConfig is pushed in order delConfig = { 'ACL_TABLE': { @@ -543,8 +554,9 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): self.postUpdateConfig(curConfig, delConfig, addConfig) return + ###########GLOBAL Configs##################################### -configDbJson = { +configDbJson = { "ACL_TABLE": { "NO-NSW-PACL-TEST": { "policy_desc": "NO-NSW-PACL-TEST", @@ -553,7 +565,7 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): "ports": [ "Ethernet9", "Ethernet11", - ] + ] }, "NO-NSW-PACL-V4": { "policy_desc": "NO-NSW-PACL-V4", @@ -564,7 +576,7 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): "Ethernet4", "Ethernet8", "Ethernet10" - ] + ] } }, "VLAN": { @@ -691,7 +703,7 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): "ports": [ "Ethernet9", "Ethernet11", - ] + ] }, "NO-NSW-PACL-V4": { "policy_desc": "NO-NSW-PACL-V4", @@ -700,7 +712,7 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): "Ethernet4", "Ethernet8", "Ethernet10" - ] + ] } }, "VLAN": { @@ -718,7 +730,7 @@ def dpb_port4_4x25G_2x50G_f_l(self, curConfig): }, "Vlan100|Ethernet11": { "tagging_mode": "untagged" - } + } }, "INTERFACE": { "Ethernet11": {}, diff --git a/tests/config_test.py b/tests/config_test.py index 89d8313d53a8..381ca803041b 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -1,5 +1,5 @@ import filecmp -import imp +import importlib import os import traceback import json @@ -37,7 +37,7 @@ def setup_class(cls): os.environ['UTILITIES_UNIT_TESTING'] = "1" print("SETUP") import config.main - imp.reload(config.main) + importlib.reload(config.main) def test_load_minigraph(self, get_cmd_module, setup_single_broadcom_asic): with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command: @@ -63,7 +63,7 @@ def setup_class(cls): print("SETUP") os.environ['UTILITIES_UNIT_TESTING'] = "2" import config.main - imp.reload(config.main) + importlib.reload(config.main) def test_qos_reload_single( self, get_cmd_module, setup_qos_mock_apis, @@ -105,7 +105,7 @@ def setup_class(cls): os.environ['UTILITIES_UNIT_TESTING'] = "2" os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" import config.main - imp.reload(config.main) + importlib.reload(config.main) def test_qos_reload_masic( self, get_cmd_module, setup_qos_mock_apis, @@ -148,5 +148,5 @@ def teardown_class(cls): # change back to single asic config from .mock_tables import dbconnector from .mock_tables import mock_single_asic - imp.reload(mock_single_asic) + importlib.reload(mock_single_asic) dbconnector.load_namespace_config() diff --git a/tests/crm_test.py b/tests/crm_test.py index 0c42bf17fcb3..369d9a51ab88 100644 --- a/tests/crm_test.py +++ b/tests/crm_test.py @@ -1,4 +1,4 @@ -import imp +import importlib import os import sys from importlib import reload @@ -1577,5 +1577,5 @@ def teardown_class(cls): os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "" from .mock_tables import dbconnector from .mock_tables import mock_single_asic - imp.reload(mock_single_asic) + importlib.reload(mock_single_asic) dbconnector.load_namespace_config() diff --git a/tests/decode_syseeprom_test.py b/tests/decode_syseeprom_test.py index 4b7758d36c89..ae3801d3694d 100644 --- a/tests/decode_syseeprom_test.py +++ b/tests/decode_syseeprom_test.py @@ -1,10 +1,10 @@ -import importlib import os import sys from unittest import mock import pytest from click.testing import CliRunner +from utilities_common.general import load_module_from_source from .mock_tables import dbconnector @@ -17,10 +17,7 @@ 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) +decode_syseeprom = load_module_from_source('decode-syseeprom', decode_syseeprom_path) # Replace swsscommon objects with mocked objects decode_syseeprom.SonicV2Connector = dbconnector.SonicV2Connector diff --git a/tests/feature_test.py b/tests/feature_test.py index 661dc9584d1e..be01eede12ab 100644 --- a/tests/feature_test.py +++ b/tests/feature_test.py @@ -1,4 +1,4 @@ -from importlib import reload +import importlib from click.testing import CliRunner @@ -395,7 +395,7 @@ def setup_class(cls): def test_config_bgp_feature_inconsistent_state(self, get_cmd_module): from .mock_tables import dbconnector from .mock_tables import mock_multi_asic_3_asics - reload(mock_multi_asic_3_asics) + importlib.reload(mock_multi_asic_3_asics) dbconnector.load_namespace_config() (config, show) = get_cmd_module db = Db() @@ -414,7 +414,7 @@ def test_config_bgp_feature_inconsistent_state(self, get_cmd_module): def test_config_bgp_feature_inconsistent_autorestart(self, get_cmd_module): from .mock_tables import dbconnector from .mock_tables import mock_multi_asic_3_asics - reload(mock_multi_asic_3_asics) + importlib.reload(mock_multi_asic_3_asics) dbconnector.load_namespace_config() (config, show) = get_cmd_module db = Db() @@ -433,7 +433,7 @@ def test_config_bgp_feature_inconsistent_autorestart(self, get_cmd_module): def test_config_bgp_feature_consistent_state(self, get_cmd_module): from .mock_tables import dbconnector from .mock_tables import mock_multi_asic - reload(mock_multi_asic) + importlib.reload(mock_multi_asic) dbconnector.load_namespace_config() (config, show) = get_cmd_module db = Db() @@ -457,7 +457,7 @@ def test_config_bgp_feature_consistent_state(self, get_cmd_module): def test_config_bgp_feature_consistent_autorestart(self, get_cmd_module): from .mock_tables import dbconnector from .mock_tables import mock_multi_asic - reload(mock_multi_asic) + importlib.reload(mock_multi_asic) dbconnector.load_namespace_config() (config, show) = get_cmd_module db = Db() @@ -484,4 +484,4 @@ def test_config_bgp_feature_consistent_autorestart(self, get_cmd_module): def teardown_class(cls): print("TEARDOWN") from .mock_tables import mock_single_asic - reload(mock_single_asic) + importlib.reload(mock_single_asic) diff --git a/tests/neighbor_advertiser_test.py b/tests/neighbor_advertiser_test.py index c6dee598af48..4a7ab41863a1 100644 --- a/tests/neighbor_advertiser_test.py +++ b/tests/neighbor_advertiser_test.py @@ -1,18 +1,21 @@ -import sys import os -import pytest -from unittest import mock import subprocess +import sys +from unittest import mock + +import pytest from swsscommon.swsscommon import ConfigDBConnector +from utilities_common.general import load_module_from_source 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) -from imp import load_source -load_source('neighbor_advertiser', scripts_path+'/neighbor_advertiser') -import neighbor_advertiser +# Load the file under test +neighbor_advertiser_path = os.path.join(scripts_path, 'neighbor_advertiser') +neighbor_advertiser = load_module_from_source('neighbor_advertiser', neighbor_advertiser_path) + class TestNeighborAdvertiser(object): @pytest.fixture diff --git a/tests/pfcstat_test.py b/tests/pfcstat_test.py index 8a63539efbc5..6e0a76d364c8 100644 --- a/tests/pfcstat_test.py +++ b/tests/pfcstat_test.py @@ -1,4 +1,3 @@ -import imp import os import shutil import sys diff --git a/tests/pfcwd_test.py b/tests/pfcwd_test.py index 9a97ff7b3362..be04a11f257b 100644 --- a/tests/pfcwd_test.py +++ b/tests/pfcwd_test.py @@ -1,4 +1,4 @@ -import imp +import importlib import os import sys from unittest.mock import patch @@ -273,7 +273,7 @@ def setup_class(cls): os.environ["UTILITIES_UNIT_TESTING"] = "2" os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic" import pfcwd.main - imp.reload(pfcwd.main) + importlib.reload(pfcwd.main) def test_pfcwd_stats_all(self): import pfcwd.main as pfcwd diff --git a/tests/port2alias_test.py b/tests/port2alias_test.py index 842bc8ee5da7..03b017f968b0 100644 --- a/tests/port2alias_test.py +++ b/tests/port2alias_test.py @@ -1,10 +1,13 @@ -import sys import os +import sys from unittest import TestCase -import imp +from utilities_common.general import load_module_from_source + +# Load the file under test +port2alias_path = os.path.join(os.path.dirname(__file__), '..', 'scripts', 'port2alias') +port2alias = load_module_from_source('port2alias', port2alias_path) -port2alias = imp.load_source('port2alias', os.path.join(os.path.dirname(__file__), '..', 'scripts', 'port2alias')) class TestPort2Alias(TestCase): def setUp(self): diff --git a/tests/psushow_test.py b/tests/psushow_test.py index c5038ba6c386..fd40a3beb876 100644 --- a/tests/psushow_test.py +++ b/tests/psushow_test.py @@ -1,10 +1,10 @@ -import importlib import os import sys from unittest import mock import pytest from click.testing import CliRunner +from utilities_common.general import load_module_from_source from .mock_tables import dbconnector @@ -17,10 +17,7 @@ # Load the file under test psushow_path = os.path.join(scripts_path, 'psushow') -loader = importlib.machinery.SourceFileLoader('psushow', psushow_path) -spec = importlib.util.spec_from_loader(loader.name, loader) -psushow = importlib.util.module_from_spec(spec) -loader.exec_module(psushow) +psushow = load_module_from_source('psushow', psushow_path) # Replace swsscommon objects with mocked objects psushow.SonicV2Connector = dbconnector.SonicV2Connector diff --git a/tests/watermarkstat_test.py b/tests/watermarkstat_test.py index 3b710896c300..cd4eae00a36a 100644 --- a/tests/watermarkstat_test.py +++ b/tests/watermarkstat_test.py @@ -1,4 +1,3 @@ -import imp import os import sys diff --git a/utilities_common/general.py b/utilities_common/general.py new file mode 100644 index 000000000000..a1982793da94 --- /dev/null +++ b/utilities_common/general.py @@ -0,0 +1,17 @@ +import importlib.machinery +import importlib.util +import sys + +def load_module_from_source(module_name, file_path): + """ + This function will load the Python source file specified by + as a module named and return an instance of the module + """ + loader = importlib.machinery.SourceFileLoader(module_name, file_path) + spec = importlib.util.spec_from_loader(loader.name, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + + sys.modules[module_name] = module + + return module diff --git a/utilities_common/util_base.py b/utilities_common/util_base.py index d32e2dbf70a5..ff5570735c55 100644 --- a/utilities_common/util_base.py +++ b/utilities_common/util_base.py @@ -49,7 +49,7 @@ def register_plugin(self, plugin, root_command): # try get information from platform API and return a default value if caught NotImplementedError def try_get(self, callback, default=None): """ - Handy function to invoke the callback and catch NotImplementedError + Handy function to invoke the callback, catch NotImplementedError and return a default value :param callback: Callback to be invoked :param default: Default return value if exception occur :return: Default return value if exception occur else return value of the callback @@ -82,4 +82,3 @@ def check_pddf_mode(self): return True else: return False -