Skip to content

Commit

Permalink
Marvell Python Automation Framework that consists of tests + infrastr…
Browse files Browse the repository at this point in the history
…ucture

Signed-off-by: Avi Milner <milner@marvell.com>
  • Loading branch information
avi-milner authored and taraschornyiplv committed Aug 11, 2021
1 parent 64bf200 commit ad03a8b
Show file tree
Hide file tree
Showing 539 changed files with 99,114 additions and 0 deletions.
Binary file not shown.
15 changes: 15 additions & 0 deletions Marvell_Framework/License.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
###################################################################################
# Marvell GPL License
#
# If you received this File from Marvell, you may opt to use, redistribute and/or
# modify this File in accordance with the terms and conditions of the General
# Public License Version 2, June 1991 (the "GPL License"), a copy of which is
# available along with the File in the license.txt file or by writing to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
# on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
#
# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
# DISCLAIMED. The GPL License provides additional details about this warranty
# disclaimer.
###################################################################################
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
###################################################################################
# Marvell GPL License
#
# If you received this File from Marvell, you may opt to use, redistribute and/or
# modify this File in accordance with the terms and conditions of the General
# Public License Version 2, June 1991 (the "GPL License"), a copy of which is
# available along with the File in the license.txt file or by writing to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
# on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
#
# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
# DISCLAIMED. The GPL License provides additional details about this warranty
# disclaimer.
###################################################################################

from CLI_GlobalFunctions.SwitchDev.Bridge.BridgeConfig import BridgeConfig
from CLI_GlobalFunctions.SwitchDev.CLICommands.Executer import GlobalGetterSetter
from PyInfra.BaseTest_SV.SV_Enums.SwitchDevInterface import SwitchDevDutInterface


class Bridge1QConfig(BridgeConfig):
MAX_VLANS = 4094

__vlanConfiguration = {} # type: dict[str, list[str]]
__version = None

@classmethod
def addInterfaceToVlan(cls, dev, vid, *args, otherDut=False):
if otherDut:
executer = GlobalGetterSetter().getterOtherDut
else:
executer = GlobalGetterSetter().getter
return executer.bridge_vlan_add(vid=vid, dev=dev, *args)

@classmethod
def removeInterfaceFromVlan(cls, dev, vid, *args, otherDut=False):
if otherDut:
executer = GlobalGetterSetter().getterOtherDut
else:
executer = GlobalGetterSetter().getter
return executer.bridge_vlan_del(vid=vid, dev=dev, *args)

@classmethod
def isTagged(cls, dev, vid):
try:
return cls.__vlanConfiguration.get(dev.name, {}).get('vlans', {}).get(vid, '') == 'tagged'
except AttributeError:
return cls.interfaceVlanSettings()[dev]['vlans'][vid] == 'tagged'

@classmethod
def getPVID(cls, dev):
try:
pvid = cls.interfaceVlanSettings()[dev.name]['pvid']
except AttributeError:
pvid = cls.interfaceVlanSettings()[dev]['pvid']

return pvid

@classmethod
def getVIDs(cls, dev):
try:
vids = cls.interfaceVlanSettings()[dev.name]['vlans']
except AttributeError:
vids = cls.interfaceVlanSettings()[dev]['vlans']

return vids

@classmethod
def interfaceVlanSettings(cls):
if not cls.__vlanConfiguration:
cls.getVlanSettings()
return cls.__vlanConfiguration

def __init__(self, switchDevInterface=SwitchDevDutInterface('br0'), otherDutChannel=False, executer=True):
super(Bridge1QConfig, self).__init__(switchDevInterface, otherDutChannel, executer)

@classmethod
def getVlanSettings(cls):
import json5
vlanTable = json5.loads(GlobalGetterSetter().getter.bridge('-j', 'vlan', 'show'))
hasInFlags = lambda x, y: 'flags' in x and not y not in x['flags']
vlanTable = {item['ifname']: item['vlans'] for item in vlanTable}
for k, v in vlanTable.items():
pvid = [str(vlans['vlan']) for vlans in v if (hasInFlags(vlans, 'PVID'))]
cls.__vlanConfiguration[k] = {
**{'vlans': {
str(vlans['vlan']): 'untagged' if hasInFlags(vlans, 'Egress Untagged') else 'tagged' for vlans
in v}},
**{'pvid': pvid[0] if pvid else None}
}

def createL2Entity(self, *args, **kwargs):
return super(Bridge1QConfig, self).createL2Entity(*args, **{'vlan_filtering':1, **kwargs} )

def setDefaultPVID(self, v):
return self._setter.ip_link_set(dev=self._switchdevInterface.name, type=self._type, vlan_default_pvid=v)

def addBridgeToVlan(self, vid, *args):
return self._getter.execute(f"bridge vlan add dev {self} vid {vid} {' '.join(list(filter(None, map(str, args))))} self")

def removeBridgeFromVlan(self, vid, *args):
return self._setter.bridge_vlan_del(vid=vid, dev=self, *args)

def isBridgeVIDUntagged(self, vid):
return self.__class__.isTagged(self._switchdevInterface.name, vid)

def getBridgePVID(self):
return self.__class__.getPVID(self._switchdevInterface)

def getBridgeVIDs(self):
return self.__class__.getVIDs(self._switchdevInterface.name)
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
###################################################################################
# Marvell GPL License
#
# If you received this File from Marvell, you may opt to use, redistribute and/or
# modify this File in accordance with the terms and conditions of the General
# Public License Version 2, June 1991 (the "GPL License"), a copy of which is
# available along with the File in the license.txt file or by writing to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
# on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
#
# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
# DISCLAIMED. The GPL License provides additional details about this warranty
# disclaimer.
###################################################################################

from CLI_GlobalFunctions.SwitchDev.CLICommands.EntityConfig import L2EntityConfig
from CLI_GlobalFunctions.SwitchDev.CLICommands.Executer import GlobalGetterSetter
from PyInfra.BaseTest_SV.SV_Enums.SwitchDevInterface import SwitchDevDutInterface


class BridgeConfig(L2EntityConfig):

def __init__(self, switchDevInterface, otherDutChannel=False, executer=True):
"""
:param switchDevInterface: the entity to be configured (e.g, bond, port, bridge)
:param otherDutChannel: True if there is another DUT; False otherwise
"""
super(BridgeConfig, self).__init__(switchDevInterface, "bridge", otherDutChannel, executer)
self._aging_time = None
self._vlan_filtering = None
self._learning = None # type: str
self._flood = None # type: str
self._vlan = None
self._ipAdrr = None # type: str

@classmethod
def getPortNumOfEntries(cls, dev, *args, timeout=10):
"""
returns the number of MAC entries of a port/interface
:param dev: the port/interface to get it's num of entries
:type dev: SwitchDevDutInterface
:param args: more filters on the MAC entries
:type args: list[str]
:return: the number of MAC entries of a port/interface
"""
return GlobalGetterSetter().getter.bridge_fdb_show('brport', dev.name, *list('| grep %s' % x for x in args),
'| wc -l', timeout=timeout)

@property
def aging_time(self):
"""
:return: the aging time of bridge entity
"""
return self._aging_time

@aging_time.setter
def aging_time(self, v):
self._setter.ip_link_set(dev=self.switchdevInterface.name, type=self._type, ageing_time=v)
self._aging_time = v

@property
def vlan_filtering(self):
return self._vlan_filtering

@vlan_filtering.setter
def vlan_filtering(self, v):
self._setter.ip_link_set(dev=self.switchdevInterface.name, type=self._type, vlan_filtering=v)
self._vlan_filtering = v

@property
def learning(self):
return self._learning

def setLearning(self, v):
for port in self.enslavedInterfaces:
ret = self._setter.bridge_link_set(dev=port.name, learning=v)
if not ret:
self._learning = v
else:
return ret

@property
def flood(self):
return self._flood

def setFloodAll(self, v):
for port in self.enslavedInterfaces:
ret = self._setter.bridge_link_set(dev=port.name, flood=v)
if not ret:
self._flood = v
else:
return ret

def setFlood(self, dev, v):
return self._setter.bridge_link_set(dev=dev, flood=v)

def setBridgeEntry(self, entry, interface, vlan):
if int(vlan) != 1:
ret = self._setter.bridge_fdb('add', entry, 'dev', interface, 'static', 'master', 'vlan', vlan)
else:
ret = self._setter.bridge_fdb('add', entry, 'dev', interface, 'static', 'master')
return ret

def fillBridgeStaticEntries(self, board_type_index='' , start_index='', dev=''):
start_index = start_index
index = board_type_index + start_index
ret = self._getter.execAsFile(f""" mac='00:00:00:00'
for ((num={start_index}; num<={index}; num++)); do
printf -v sfx ':%02X:%02X' $((num>>8)) $((num&255))
bridge fdb add "${{mac}}${{sfx}}" dev {dev} static master
done""")
return ret

def remBridgeEntry(self, entry, interface, vlan):
if int(vlan) != 1:
ret = self._setter.bridge_fdb('del', entry, 'dev', interface, 'static', 'master', 'vlan', vlan)
else:
ret = self._setter.bridge_fdb('del', entry, 'dev', interface, 'static', 'master')
return ret

def addInterfaceToVlan(self, dev, vid, *args):
ret = self._setter.bridge_vlan_add(vid=vid, dev=dev, *args)
if not ret:
self._vlan = vid
else:
return ret

def remInterfaceFromVlan(self, dev, vid, *args):
ret = self._setter.bridge_vlan_del(vid=vid, dev=dev, *args)
if not ret:
self._vlan = None
else:
return ret

def getPortEntries(self, interface):
return self._getter.bridge_fdb_show(brport=interface) # '|', 'grep', 'extern_learn')

def getBridgeEntries(self, bridge):
return self._getter.bridge_fdb_show(bridge)

def getBridgeNumOfEntries(self, bridge):
#return self._getter.brctl_showmacs(bridge, ' | ', 'wc', '-l')
return self._getter.bridge_fdb_show('br', bridge, ' | ', 'grep', "'extern_learn.*offload'", ' | ', 'wc', '-l')

def getStaticBridgeNumOfEntries(self, bridge):
#return self._getter.brctl_showmacs(bridge, ' | ', 'wc', '-l')
return self._getter.bridge_fdb_show('br', bridge, ' | ', 'grep', "'offload.*static'", ' | ', 'wc', '-l')

def setBridgeSTP(self, bridge, mode):
return self._setter.brctl_stp(bridge, mode)

def setIP(self, addr, mask):
ret = self._setter.ip_addr_add(f"{addr}/{mask}", 'dev', self.switchdevInterface.name)
if not ret:
self._ipAdrr = addr

def setIPVlanDev(self, addr, mask, vlan):
return self._setter.ip_addr_add(f"{addr}/{mask}", 'dev', f'{self.switchdevInterface.name}.{vlan}')

def delIP(self, addr, mask):
return self._setter.ip_addr_del(f"{addr}/{mask}", 'dev', self.switchdevInterface.name)

def addVlanDev(self, bridge, vlan):
return self._setter.ip_link_add_link(bridge, 'name', f'{bridge}.{vlan}', 'type', 'vlan', 'id', vlan)

def addBridgeToVlan(self, bridge, vlan):
return self._setter.bridge_vlan_add_dev(bridge, 'vid', vlan, 'self')

def changeSelfMac(self, mac):
return self._getter.execute(f'ifconfig {self} hw ether {mac}')

@classmethod
def setMaxSTPInstances(cls, max_instances):
for i in range(max_instances):
ret = GlobalGetterSetter().getter.ip_link_add(f'br{i}', 'type', 'bridge', 'stp_state', '1')
if ret:
return ret

@classmethod
def getMaxSTPInstances(cls):
return GlobalGetterSetter().getter.ifconfig('-a', ' | ', 'grep', 'br.*', ' | ', 'wc', '-l')

@classmethod
def removeMaxSTPInstances(cls, max_instances):
for i in range(max_instances):
ret = GlobalGetterSetter().getter.ip_link_del(f'br{i}', 'type', 'bridge')
if ret:
return ret

def maxVLANSFromFile(self, index1='', index2='', dev1='', dev2=''):

ret = self._getter.execAsFile(f"""for ((i=1; i<={index1}; i++)); do bridge vlan add dev {dev1} vid $i; done
for ((j=1; j<={index2}; j++)); do bridge vlan add dev {dev2} vid $j; done""")
return ret
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
###################################################################################
# Marvell GPL License
#
# If you received this File from Marvell, you may opt to use, redistribute and/or
# modify this File in accordance with the terms and conditions of the General
# Public License Version 2, June 1991 (the "GPL License"), a copy of which is
# available along with the File in the license.txt file or by writing to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
# on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
#
# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
# WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
# DISCLAIMED. The GPL License provides additional details about this warranty
# disclaimer.
###################################################################################

Loading

0 comments on commit ad03a8b

Please sign in to comment.