From 99de1678e25fd8499dadb2044802a1b6ab388b50 Mon Sep 17 00:00:00 2001 From: madhanmellanox <62459540+madhanmellanox@users.noreply.github.com> Date: Wed, 4 Nov 2020 20:25:15 -0800 Subject: [PATCH] [Mellanox] SKU creator Tool (#1163) I added a new script file sonic_sku_create.py to generate a new HWSKU based on XML file or Minigraph. But, focus is on creating HWSKU based on XML file and not on the minigraph and l2 mode. I also added a unit test pyTest script sku_create_test.py in sonic-utilities-test folder to test the script in Unit Testing mode. Motivation: To create SKU for Mellanox platforms based on XML file with Port related inputs and also through Minigraph file. This tool also allows to split a port or unsplit ports based on configuration which modifies the port related information in port_config.ini and config_db.json usage: sonic_sku_create.py [-h] [-v] (-f FILE | -m [MINIGRAPH_FILE] | -j JSON_FILE | -pp PORT_SPLIT PORT_SPLIT) [-b BASE] [-r] [-k HWSKU] [-p] [-vv] Create a new SKU optional arguments: -h, --help show this help message and exit -v, --version show program's version number and exit -f FILE, --file FILE SKU definition from xml file. -f OR -m or -j must be provided when creating a new SKU -m [MINIGRAPH_FILE], --minigraph_file [MINIGRAPH_FILE] SKU definition from minigraph file. -f OR -m or -j must be provided when creating a new SKU -j JSON_FILE, --json_file JSON_FILE SKU definition from config_db.json file. -f OR -m OR -j must be provided when creating a new SKU -pp PORT_SPLIT PORT_SPLIT, --port_split PORT_SPLIT PORT_SPLIT port name and split -b BASE, --base BASE SKU base definition -r, --remove Remove SKU folder -k HWSKU, --hwsku HWSKU SKU name to be used when creating a new SKU or for L2 configuration mode -p, --print Print port_config.ini without creating a new SKU -vv, --verbose Verbose output --- scripts/sonic_sku_create.py | 776 ++++++++++++++++++ .../ACS-MSN2700/buffers.json.j2 | 2 + .../ACS-MSN2700/buffers_defaults_t0.j2 | 90 ++ .../ACS-MSN2700/buffers_defaults_t1.j2 | 90 ++ .../ACS-MSN2700/pg_profile_lookup.ini | 17 + .../ACS-MSN2700/port_config.ini | 33 + .../sku_create_input/ACS-MSN2700/qos.json | 166 ++++ .../sku_create_input/ACS-MSN2700/sai.profile | 1 + .../Mellanox-SN2700-D48C8.xml | 72 ++ .../Mellanox-SN2700-D48C8/buffers.json.j2 | 2 + .../buffers_defaults_t0.j2 | 90 ++ .../buffers_defaults_t1.j2 | 90 ++ .../pg_profile_lookup.ini | 17 + .../Mellanox-SN2700-D48C8/port_config.ini | 57 ++ .../Mellanox-SN2700-D48C8/port_config.ini.bak | 57 ++ .../Mellanox-SN2700-D48C8/port_config.ini.new | 60 ++ .../port_config.ini.orig | 57 ++ .../Mellanox-SN2700-D48C8/qos.json | 166 ++++ .../Mellanox-SN2700-D48C8/sai.profile | 1 + .../sai_2700_48x50g_8x100g.xml | 267 ++++++ .../sku_create_input/default_sku | 1 + sonic-utilities-tests/sku_create_test.py | 74 ++ 22 files changed, 2186 insertions(+) create mode 100755 scripts/sonic_sku_create.py create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers.json.j2 create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t0.j2 create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t1.j2 create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/pg_profile_lookup.ini create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/port_config.ini create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/qos.json create mode 100644 sonic-utilities-tests/sku_create_input/ACS-MSN2700/sai.profile create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8.xml create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers.json.j2 create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/pg_profile_lookup.ini create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.bak create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.new create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.orig create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/qos.json create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai.profile create mode 100644 sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml create mode 100644 sonic-utilities-tests/sku_create_input/default_sku create mode 100644 sonic-utilities-tests/sku_create_test.py diff --git a/scripts/sonic_sku_create.py b/scripts/sonic_sku_create.py new file mode 100755 index 000000000000..bb1fae450cf2 --- /dev/null +++ b/scripts/sonic_sku_create.py @@ -0,0 +1,776 @@ +#! /usr/bin/env python2 +""" +usage: sonic_sku_create.py [-h] [-v] [-f FILE] [-m [MINIGRAPH_FILE]] [-b BASE] + [-r] [-k HWSKU] + [-p] [-vv] +Create a new SKU + +optional arguments: + -h, --help Show this help message and exit + -v, --version Show program's version number and exit + -f FILE, --file FILE SKU definition from xml file. -f OR -m must be provided when creating a new SKU + -m [MINIGRAPH_FILE], --minigraph_file [MINIGRAPH_FILE] + SKU definition from minigraph file. -f OR -m must be provided when creating a new SKU + -b BASE, --base BASE SKU base definition + -r, --remove Remove SKU folder + -k HWSKU, --hwsku HWSKU + SKU name to be used when creating a new SKU or for L2 configuration mode + -p, --print Print port_config.ini without creating a new SKU + -vv, --verbose Verbose output + + +""" + +from __future__ import print_function + +import argparse +import json +import os +import re +import subprocess +import traceback +import sys +import shutil +import copy +from collections import OrderedDict + +from tabulate import tabulate +from lxml import etree as ET +from lxml.etree import QName + +minigraph_ns = "Microsoft.Search.Autopilot.Evolution" +minigraph_ns1 = "http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" +INTERFACE_KEY = "Ethernet" + +### port_config.ini header +PORTCONFIG_HEADER = ["# name", "lanes", "alias", "index", "speed"] +platform_4 = ['x86_64-mlnx_lssn2700-r0','x86_64-mlnx_msn2010-r0','x86_64-mlnx_msn2100-r0','x86_64-mlnx_msn2410-r0','x86_64-mlnx_msn2700-r0','x86_64-mlnx_msn2740-r0','x86_64-mlnx_msn3700c-r0','x86_64-mlnx_msn3700-r0','x86_64-mlnx_msn3800-r0'] +platform_8 = ['x86_64-mlnx_msn4600c-r0','x86_64-mlnx_msn4700-r0'] + +bko_dict_4 = { + "1x100": { "lanes":4, "speed":100000, "step":4, "bko":0, "name": "etp" }, + "1x40": { "lanes":4, "speed":40000, "step":4, "bko":0, "name": "etp" }, + "1x50": { "lanes":4, "speed":50000, "step":4, "bko":0, "name": "etp" }, + "1x25": { "lanes":4, "speed":25000, "step":4, "bko":0, "name": "etp" }, + "1x10": { "lanes":4, "speed":10000, "step":4, "bko":0, "name": "etp" }, + "1x1": { "lanes":4, "speed":1000, "step":4, "bko":0, "name": "etp" }, + "4x10": { "lanes":4, "speed":10000, "step":1, "bko":1, "name": "etp" }, + "4x25": { "lanes":4, "speed":25000, "step":1, "bko":1, "name": "etp" }, + "2x50": { "lanes":4, "speed":25000, "step":2, "bko":1, "name": "etp" }, +} + +bko_dict_8 = { + "1x400": { "lanes":8, "speed":400000, "step":8, "bko":0, "name": "etp" }, + "2x200": { "lanes":8, "speed":200000, "step":4, "bko":1, "name": "etp" }, + "2x100": { "lanes":8, "speed":100000, "step":4, "bko":1, "name": "etp" }, + "4x100": { "lanes":8, "speed":100000, "step":2, "bko":1, "name": "etp" }, + "4x50": { "lanes":8, "speed":50000, "step":2, "bko":1, "name": "etp" }, + "4x25": { "lanes":4, "speed":25000, "step":1, "bko":1, "name": "etp" }, + "4x10": { "lanes":4, "speed":10000, "step":1, "bko":1, "name": "etp" }, +} + +class SkuCreate(object): + """ + Tool for SKU creator + """ + + def __init__(self): + + self.portconfig_dict = {} + self.platform_specific_dict = {"x86_64-mlnx_msn2700-r0":self.msn2700_specific} + self.default_lanes_per_port = [] + self.platform = None + self.base_lanes = None + self.fpp = [] + self.fpp_split = {} + self.num_of_fpp = 0 + self.sku_name = None + self.default_sku_path = None + self.base_sku_name = None + self.base_sku_dir = None + self.base_file_path = None + self.new_sku_dir = None + self.print_mode = False + self.remove_mode = False + self.verbose = None + self.bko_dict = {} + + def sku_def_parser(self, sku_def): + # Parsing XML sku definition file to extract Interface speed and InterfaceName(alias) to be used to analyze split configuration + # Rest of the fields are used as placeholders for portconfig_dict [name,lanes,SPEED,ALIAS,index] + try: + f = open(str(sku_def),"r") + except IOError: + print("Couldn't open file: " + str(sku_def), file=sys.stderr) + exit(1) + element = ET.parse(f) + + root = element.getroot() + if (self.verbose): + print( "tag=%s, attrib=%s" % (root.tag, root.attrib)) + self.sku_name = root.attrib["HwSku"] + self.new_sku_dir = self.default_sku_path+"/"+self.sku_name+ '/' + idx = 1 + for child in root: + if child.tag == "Ethernet": + for interface in child: + for eth_iter in interface.iter(): + if eth_iter is not None: + self.portconfig_dict[idx] = ["Ethernet"+str(idx),[1,2,3,4], eth_iter.get("InterfaceName"), str(idx), eth_iter.get("Speed")] + if (self.verbose): + print("sku_def_parser:portconfig_dict[",idx,"] -> ",self.portconfig_dict[idx]) + idx += 1 + f.close() + + def parse_deviceinfo(self, meta, hwsku): + # Parsing minigraph sku definition file to extract Interface speed and InterfaceName(alias) to be used to analyze split configuration + # Rest of the fields are used as placeholders for portconfig_dict [name,lanes,SPEED,ALIAS,index] + idx = 1 + match = None + for device_info in meta.findall(str(QName(minigraph_ns, "DeviceInfo"))): + dev_sku = device_info.find(str(QName(minigraph_ns, "HwSku"))).text + if dev_sku == hwsku : + match = True + interfaces = device_info.find(str(QName(minigraph_ns, "EthernetInterfaces"))).findall(str(QName(minigraph_ns1, "EthernetInterface"))) + + for interface in interfaces: + alias = interface.find(str(QName(minigraph_ns, "InterfaceName"))).text + speed = interface.find(str(QName(minigraph_ns, "Speed"))).text + port_name = "Ethernet"+str(idx) + self.portconfig_dict[idx] = [port_name,[1,2,3,4], alias, idx, speed] + if (self.verbose): + print("parse_device_info(minigraph)--> ",self.portconfig_dict[idx]) + idx +=1 + + if match is None : + raise ValueError("Couldn't find a SKU ", hwsku, "in minigraph file") + + + def minigraph_parser(self, minigraph_file): + # Function to parse minigrpah XML file and generate SKU file (port_config.ini) by populating information regarding the ports that are extracted + #from minigraph file + root = ET.parse(minigraph_file).getroot() + if (self.verbose): + print( "tag=%s, attrib=%s" % (root.tag, root.attrib)) + hwsku_qn = QName(minigraph_ns, "HwSku") + for child in root: + if (self.verbose): + print("TAG: ",child.tag, "TEXT: ",child.text) + if child.tag == str(hwsku_qn): + hwsku = child.text + + self.new_sku_dir = self.default_sku_path+"/"+hwsku+ '/' + + for child in root: + if (self.verbose): + print( "tag=%s, attrib=%s" % (child.tag, child.attrib)) + if child.tag == str(QName(minigraph_ns, "DeviceInfos")): + self.parse_deviceinfo(child, hwsku) + + def check_json_lanes_with_bko(self, data, port_idx): + # Function to find matching entry in bko_dict that matches Port details from config_db.json file + port_str = "Ethernet{:d}".format(port_idx) + port_dict = [] + port_bmp = 1 + port_dict = data['PORT'].get(port_str) + if "speed" in port_dict: + port_speed = port_dict.get("speed") + int_port_speed = int(port_speed) + else: + print(port_str, "does not contain speed key, Exiting...", file=sys.stderr) + exit(1) + for i in range(1,self.base_lanes): + curr_port_str = "Ethernet{:d}".format(port_idx+i) + if curr_port_str in data['PORT']: + curr_port_dict = data['PORT'].get(curr_port_str) + if "speed" in curr_port_dict: + curr_speed = curr_port_dict.get("speed") + else: + print(curr_port_str, "does not contain speed key, Exiting...", file=sys.stderr) + exit(1) + if port_speed != curr_speed: + print(curr_port_str, "speed is different from that of ",port_str,", Exiting...", file=sys.stderr) + exit(1) + if "alias" in curr_port_dict: + curr_alias = curr_port_dict.get("alias") + else: + print(curr_port_str, "does not contain alias key, Exiting...", file=sys.stderr) + exit(1) + if "lanes" in curr_port_dict: + curr_lanes = curr_port_dict.get("lanes") + else: + print(curr_port_str, "does not contain lanes key, Exiting...", file=sys.stderr) + exit(1) + port_bmp |= (1< 1: + for j in range(1,step): + lanes_str += ",{:d}".format(lane_index + j) + if bko == 0: + alias_str = "etp{:d}".format(alias_index) + else: + alias_str = "etp{:d}{:s}".format(alias_index,alias_arr[i/step]) + index_str = "{:d}".format(alias_index-1) + lanes_str_result = lanes_str_result + ":" + lanes_str + out_str = "{:15s} {:20s} {:11s} {:9s} {:10s}\n".format(port_str,lanes_str,alias_str,index_str,str(speed)) + f_out.write(out_str) + else: + if port_found == True: + if alias_index == matched_alias_index: + continue + else: + f_out.write(orig_line) + + else: + f_out.write(orig_line) + + f_in.close() + f_out.close() + return lanes_str_result + + def break_in_cfg(self, cfg_file, port_name, port_split, lanes_str_result): + # Function to split or unsplit a port in config_db.json file + if not os.access(os.path.dirname(cfg_file), os.W_OK): + print("Skipping config_db.json updates for a write permission issue") + return + + bak_file = cfg_file + ".bak" + shutil.copy(cfg_file, bak_file) + + new_file = cfg_file + ".new" + + with open(bak_file) as f: + data = json.load(f) + + pattern = '^Ethernet([0-9]{1,})' + m = re.match(pattern,port_name) + port_idx = int(m.group(1)) + mtu = 9100 + + for port_index in range (port_idx,port_idx+self.base_lanes): + port_str = "Ethernet" + str(port_index) + print("Port String ",port_str) + + if data['PORT'].get(port_str) != None: + port_instance = data['PORT'].get(port_str) + if "mtu" in port_instance: + mtu = port_instance.get("mtu") + data['PORT'].pop(port_str) + print("Removed Port instance: ", port_str, port_instance) + print("Please remove port ", port_str, " configurations that are part of other features") + + port_inst = {} + j = 1 + lanes_arr = lanes_str_result.split(':') + step = self.bko_dict[port_split]["step"] + alias_arr = ['a','b','c','d'] + pattern = '^([0-9]{1,})x([0-9]{1,})' + m = re.match(pattern,port_split) + speed = int(m.group(2)) + bko = self.bko_dict[port_split]["bko"] + + for i in range(0,self.base_lanes,step): + port_str = "Ethernet{:d}".format(port_idx + i/step) + lanes_str = lanes_arr[j] + j += 1 + + if bko == 0: + alias_str = "etp{:d}".format((port_idx/self.base_lanes)+1) + else: + alias_str = "etp{:d}{:s}".format((port_idx/self.base_lanes)+1,alias_arr[i/step]) + print("i= ",i," alias_str= ",alias_str) + port_inst["lanes"] = lanes_str + port_inst["alias"] = alias_str + port_inst["speed"] = speed*1000 + port_inst["mtu"] = mtu + + xxx = copy.deepcopy(port_inst) + data['PORT'][port_str] = xxx + print(port_str, data['PORT'][port_str]) + + with open(new_file, 'w') as outfile: + json.dump(data, outfile, indent=4, sort_keys=True) + + print("--------------------------------------------------------") + + def break_a_port(self, port_name, port_split): + # Function to split or unsplit a port based on user input in both port_config.ini file and config_db.json file + new_file = self.ini_file + ".new" + lanes_str_result = self.break_in_ini(self.ini_file,port_name,port_split) + self.port_config_split_analyze(self.ini_file) + self.form_port_config_dict_from_ini(self.ini_file) + self.platform_specific() + shutil.copy(new_file,self.ini_file) + if lanes_str_result is None: + print("break_in_ini function returned empty lanes string, Exiting...", file=sys.stderr) + exit(1) + self.break_in_cfg(self.cfg_file,port_name,port_split,lanes_str_result) + + def split_analyze(self): + # Analyze the front panl ports split based on the interfaces alias names + # fpp_split is a hash with key=front panel port and values is a list of lists ([alias],[index]) + alias_index = PORTCONFIG_HEADER.index('alias') + for idx,ifc in self.portconfig_dict.items(): + pattern = '^etp([0-9]{1,})([a-d]?)' + m = re.match(pattern,str(ifc[alias_index])) + if int(m.group(1)) not in self.fpp_split : + self.fpp_split[int(m.group(1))] = [[ifc[alias_index]],[idx]] #1 + else: + self.fpp_split[int(m.group(1))][0].append(str(ifc[alias_index])) #+= 1 + self.fpp_split[int(m.group(1))][1].append(idx) + if (self.verbose): + print("split_analyze -> ",m.group(1), " : ", self.fpp_split[int(m.group(1))]) + self.num_of_fpp = len(self.fpp_split.keys()) + + def get_default_lanes(self): + #Internal function to get lanes of the ports accroding to the base default SKU + try: + with open(self.base_file_path,"r") as f: + line_header = f.next().split() # get the file header split into columns + if line_header[0] == "#" : del line_header[0] # if hashtag is in a different column, remove it to align column header and data + alias_index = line_header.index('alias') + lanes_index = line_header.index('lanes') + pattern = '^etp([0-9]{1,})' + for line in f: + line_arr = line.split() + m = re.match(pattern,line_arr[alias_index]) + self.default_lanes_per_port.insert(int(m.group(1))-1,line_arr[lanes_index]) + if (self.verbose): + print("get_default_lanes -> ",m.group(1), " : ", self.default_lanes_per_port[int(m.group(1))-1]) + f.close() + except IOError: + print("Could not open file "+ self.base_file_path, file=sys.stderr) + exit(1) + + def set_lanes(self): + #set lanes and index per interfaces based on split + lanes_index = PORTCONFIG_HEADER.index('lanes') + index_index = PORTCONFIG_HEADER.index('index') + name_index = PORTCONFIG_HEADER.index('# name') + + for fp, values in self.fpp_split.items(): + splt_arr = sorted(values[0]) + idx_arr = sorted(values[1]) + + splt = len(splt_arr) + pattern = '(\d+),(\d+),(\d+),(\d+)' #Currently the assumption is that the default(base) is 4 lanes + + m = re.match(pattern,self.default_lanes_per_port[fp-1]) + if (splt == 1): + self.portconfig_dict[idx_arr[0]][lanes_index] = m.group(1)+","+m.group(2)+","+m.group(3)+","+m.group(4) + self.portconfig_dict[idx_arr[0]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[0]][name_index] = "Ethernet"+str((fp-1)*4) + if (self.verbose): + print("set_lanes -> FP: ",fp, "Split: ",splt) + print("PortConfig_dict ",idx_arr[0],":", self.portconfig_dict[idx_arr[0]]) + elif (splt == 2): + self.portconfig_dict[idx_arr[0]][lanes_index] = m.group(1)+","+m.group(2) + self.portconfig_dict[idx_arr[1]][lanes_index] = m.group(3)+","+m.group(4) + self.portconfig_dict[idx_arr[0]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[1]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[0]][name_index] = "Ethernet"+str((fp-1)*4) + self.portconfig_dict[idx_arr[1]][name_index] = "Ethernet"+str((fp-1)*4+2) + if (self.verbose): + print("set_lanes -> FP: ",fp, "Split: ",splt) + print("PortConfig_dict ",idx_arr[0],":", self.portconfig_dict[idx_arr[0]]) + print("PortConfig_dict ",idx_arr[1],":", self.portconfig_dict[idx_arr[1]]) + elif (splt == 4): + self.portconfig_dict[idx_arr[0]][lanes_index] = m.group(1) + self.portconfig_dict[idx_arr[1]][lanes_index] = m.group(2) + self.portconfig_dict[idx_arr[2]][lanes_index] = m.group(3) + self.portconfig_dict[idx_arr[3]][lanes_index] = m.group(4) + self.portconfig_dict[idx_arr[0]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[1]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[2]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[3]][index_index] = str(fp-1) + self.portconfig_dict[idx_arr[0]][name_index] = "Ethernet"+str((fp-1)*4) + self.portconfig_dict[idx_arr[1]][name_index] = "Ethernet"+str((fp-1)*4+1) + self.portconfig_dict[idx_arr[2]][name_index] = "Ethernet"+str((fp-1)*4+2) + self.portconfig_dict[idx_arr[3]][name_index] = "Ethernet"+str((fp-1)*4+3) + if (self.verbose): + print("set_lanes -> FP: ",fp, "Split: ",splt) + print("PortConfig_dict ",idx_arr[0],":", self.portconfig_dict[idx_arr[0]]) + print("PortConfig_dict ",idx_arr[1],":", self.portconfig_dict[idx_arr[1]]) + print("PortConfig_dict ",idx_arr[2],":", self.portconfig_dict[idx_arr[2]]) + print("PortConfig_dict ",idx_arr[3],":", self.portconfig_dict[idx_arr[3]]) + self.platform_specific() + + def create_port_config(self): + #create a port_config.ini file based on the sku definition + if not os.path.exists(self.new_sku_dir): + print("Error - path:", self.new_sku_dir, " doesn't exist",file=sys.stderr) + exit(1) + + try: + f = open(self.new_sku_dir+"port_config.ini","w+") + except IOError: + print("Could not open file "+ self.new_sku_dir+"port_config.ini", file=sys.stderr) + exit(1) + header = PORTCONFIG_HEADER # ["name", "lanes", "alias", "index"] + port_config = [] + for line in self.portconfig_dict.values(): + port_config.append(line) + + port_config.sort(key=lambda x: (int(re.search(('\d+'),x[0]).group(0)))) # sort the list with interface name + f.write(tabulate(port_config, header,tablefmt="plain")) + f.close() + + def print_port_config(self): + #print a port_config.ini file based on the sku definition + header = PORTCONFIG_HEADER # ["name", "lanes", "alias", "index"] + port_config = [] + for line in self.portconfig_dict.values(): + port_config.append(line) + + port_config.sort(key=lambda x: (int(re.search(('\d+'),x[0]).group(0)))) # sort the list with interface name + print(tabulate(port_config, header,tablefmt="plain")) + + + def create_sku_dir(self): + # create a new SKU directory based on the base SKU + if (os.path.exists(self.new_sku_dir)): + print("SKU directory: "+self.new_sku_dir+ " already exists\n Please use -r flag to remove the SKU dir first", file=sys.stderr) + exit(1) + try: + shutil.copytree(self.base_sku_dir, self.new_sku_dir) + except OSError as e: + print(e.message, file=sys.stderr) + + def remove_sku_dir(self): + # remove SKU directory + if (self.new_sku_dir == self.base_sku_dir): + print("Removing the base SKU" + self.new_sku_dir + " is not allowed", file=sys.stderr) + exit(1) + try: + if not os.path.exists(self.new_sku_dir): + print("Trying to remove a SKU "+ self.new_sku_dir + " that doesn't exists, Ignoring -r command") + while True: + answer = raw_input("You are about to permanently delete the SKU "+ self.new_sku_dir+" !! \nDo you want to continue (Yes/No)?") + if (answer == "Yes" or answer == "No"): + break + else: + print("Valid answers are Yes or No") + if (answer == "Yes"): + shutil.rmtree(self.new_sku_dir) + print("SKU directory: "+ self.new_sku_dir + " was removed") + else: + print("SKU directory: "+ self.new_sku_dir + " was NOT removed") + except OSError as e: + print(e.message, file=sys.stderr) + + def platform_specific(self): + # Function that checks for Platform specific restrictions + func = self.platform_specific_dict.get(self.platform, lambda: "nothing") + return func() + + + def msn2700_specific(self): + # Function that implements the check for platform restrictions of 2700 platform + for fp, values in self.fpp_split.items(): + splt_arr = sorted(values[0]) + splt = len(splt_arr) + try : + if ((fp%2) == 1 and splt == 4): + next_fp = fp+1 + if (next_fp not in self.fpp_split): + continue + next_fp_idx_arr = sorted(self.fpp_split[next_fp][1]) + for i in next_fp_idx_arr : + if (self.verbose): + print("msn2700_specific -> Removing ", self.portconfig_dict[i]) + self.portconfig_dict.pop(i) + print("MSN2700 - Front panel port ",next_fp, " should be removed due to port ",fp,"Split by 4") + raise ValueError() + elif ((fp%2) == 0 and splt == 4): + print("MSN2700 - even front panel ports (",fp,") are not allowed to split by 4") + raise ValueError() + except ValueError: + print("Error - Illegal split by 4 ", file=sys.stderr) + exit(1) + + +def main(argv): + parser = argparse.ArgumentParser(description='Create a new SKU', + version='1.0.0', + formatter_class=argparse.RawTextHelpFormatter) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-f', '--file', action='store', nargs=1, help='SKU definition from xml file. -f OR -m or -j must be provided when creating a new SKU', default=None) + group.add_argument('-m', '--minigraph_file', action='store', nargs='?', help='SKU definition from minigraph file. -f OR -m or -j must be provided when creating a new SKU', const="/etc/sonic/minigraph.xml") + group.add_argument('-j', '--json_file', action='store', nargs=1, help='SKU definition from config_db.json file. -f OR -m OR -j must be provided when creating a new SKU', default=None) + group.add_argument('-s', '--port_split', action='store', nargs=2, help='port name and split', default=None) + parser.add_argument('-b', '--base', action='store', help='SKU base definition', default=None) + parser.add_argument('-r', '--remove', action='store_true', help='Remove SKU folder') + parser.add_argument('-k', '--hwsku', action='store', help='SKU name to be used when creating a new SKU or for L2 configuration mode', default=None) + parser.add_argument('-p', '--print', action='store_true', help='Print port_config.ini without creating a new SKU', default=False) + parser.add_argument('--verbose', action='store_true', help='Verbose output', default=False) + parser.add_argument('-d', '--default_sku_path', action='store',nargs=1, help='Specify Default SKU path', default=None) + + args = parser.parse_args() + + try: + sku = SkuCreate() + sku.verbose = args.verbose + if (args.verbose): + print("ARGS: ", args) + + + if args.default_sku_path: + sku.default_sku_path = args.default_sku_path[0] + else: + try: + sku.platform = subprocess.check_output("sonic-cfggen -H -v DEVICE_METADATA.localhost.platform",shell=True) #self.metadata['platform'] + sku.platform = sku.platform.rstrip() + except KeyError: + print("Couldn't find platform info in CONFIG_DB DEVICE_METADATA", file=sys.stderr) + exit(1) + sku.default_sku_path = '/usr/share/sonic/device/' + sku.platform + + if args.base: + sku.base_sku_name = args.base + else: + f=open(sku.default_sku_path + '/' + "default_sku","r") + sku.base_sku_name=f.read().split()[0] + + sku.base_sku_dir = sku.default_sku_path + '/' + sku.base_sku_name + '/' + sku.base_file_path = sku.base_sku_dir + "port_config.ini" + + if args.file: + sku.sku_def_parser(args.file[0]) + elif args.minigraph_file: + sku.minigraph_parser(args.minigraph_file) + elif args.json_file: + if sku.platform in platform_4: + sku.base_lanes = 4 + sku.bko_dict = bko_dict_4 + else: + sku.base_lanes = 8 + sku.bko_dict = bko_dict_8 + + if args.remove: + sku.remove_mode = True + if args.print: + sku.print_mode = True + sku.cfg_file = "/etc/sonic/config_db.json" + sku.json_file_parser(args.json_file[0]) + return + elif args.port_split: + sku.break_a_port(args.port_split[0], args.port_split[1]) + return + + if args.file or args.minigraph_file: + if args.remove: + sku.remove_sku_dir() + return + sku.get_default_lanes() + sku.split_analyze() + sku.set_lanes() + if args.print: + sku.print_port_config() + else: + sku.create_sku_dir() + sku.create_port_config() + print("Created a new sku (Location: " + sku.new_sku_dir+")") + + except Exception : + traceback.print_exc(file=sys.stderr) + sys.exit(1) + +if __name__ == "__main__": + main(sys.argv) diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers.json.j2 b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t0.j2 b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..475a0227143c --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t0.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t1.j2 b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c292ecc2f21a --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/buffers_defaults_t1.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/pg_profile_lookup.ini b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/port_config.ini b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/port_config.ini new file mode 100644 index 000000000000..1e1906ff0ef5 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias +Ethernet0 0,1,2,3 etp1 +Ethernet4 4,5,6,7 etp2 +Ethernet8 8,9,10,11 etp3 +Ethernet12 12,13,14,15 etp4 +Ethernet16 16,17,18,19 etp5 +Ethernet20 20,21,22,23 etp6 +Ethernet24 24,25,26,27 etp7 +Ethernet28 28,29,30,31 etp8 +Ethernet32 32,33,34,35 etp9 +Ethernet36 36,37,38,39 etp10 +Ethernet40 40,41,42,43 etp11 +Ethernet44 44,45,46,47 etp12 +Ethernet48 48,49,50,51 etp13 +Ethernet52 52,53,54,55 etp14 +Ethernet56 56,57,58,59 etp15 +Ethernet60 60,61,62,63 etp16 +Ethernet64 64,65,66,67 etp17 +Ethernet68 68,69,70,71 etp18 +Ethernet72 72,73,74,75 etp19 +Ethernet76 76,77,78,79 etp20 +Ethernet80 80,81,82,83 etp21 +Ethernet84 84,85,86,87 etp22 +Ethernet88 88,89,90,91 etp23 +Ethernet92 92,93,94,95 etp24 +Ethernet96 96,97,98,99 etp25 +Ethernet100 100,101,102,103 etp26 +Ethernet104 104,105,106,107 etp27 +Ethernet108 108,109,110,111 etp28 +Ethernet112 112,113,114,115 etp29 +Ethernet116 116,117,118,119 etp30 +Ethernet120 120,121,122,123 etp31 +Ethernet124 124,125,126,127 etp32 diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/qos.json b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/qos.json new file mode 100644 index 000000000000..3e01af3f2c64 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/qos.json @@ -0,0 +1,166 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + diff --git a/sonic-utilities-tests/sku_create_input/ACS-MSN2700/sai.profile b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/sai.profile new file mode 100644 index 000000000000..9a9a38aeb068 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/ACS-MSN2700/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sai_2700.xml diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8.xml b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8.xml new file mode 100644 index 000000000000..749218e93c3c --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers.json.j2 b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers.json.j2 new file mode 100644 index 000000000000..1083a6210fc9 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't0' %} +{%- include 'buffers_config.j2' %} diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..475a0227143c --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t0.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '4194304' %} +{% set ingress_lossy_pool_size = '7340032' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '7340032' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..c292ecc2f21a --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/buffers_defaults_t1.j2 @@ -0,0 +1,90 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '2097152' %} +{% set ingress_lossy_pool_size = '5242880' %} +{% set egress_lossless_pool_size = '16777152' %} +{% set egress_lossy_pool_size = '5242880' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + } + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { + "{{ port_names }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + } + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { + "{{ port_names }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, + "{{ port_names }}|0-1": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + } + } +{%- endmacro %} + + diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/pg_profile_lookup.ini b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/pg_profile_lookup.ini new file mode 100644 index 000000000000..b66b129fe43f --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 34816 18432 16384 0 + 25000 5m 34816 18432 16384 0 + 40000 5m 34816 18432 16384 0 + 50000 5m 34816 18432 16384 0 + 100000 5m 36864 18432 18432 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 39936 18432 21504 0 + 40000 40m 41984 18432 23552 0 + 50000 40m 41984 18432 23552 0 + 100000 40m 54272 18432 35840 0 + 10000 300m 49152 18432 30720 0 + 25000 300m 71680 18432 53248 0 + 40000 300m 94208 18432 75776 0 + 50000 300m 94208 18432 75776 0 + 100000 300m 184320 18432 165888 0 diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini new file mode 100644 index 000000000000..f9f465f1a3ea --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.bak b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.bak new file mode 100644 index 000000000000..f9f465f1a3ea --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.bak @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.new b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.new new file mode 100644 index 000000000000..49322c57cca9 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.new @@ -0,0 +1,60 @@ +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32 etp9a 8 25000 +Ethernet33 33 etp9b 8 25000 +Ethernet34 34 etp9c 8 25000 +Ethernet35 35 etp9d 8 25000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.orig b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.orig new file mode 100644 index 000000000000..f9f465f1a3ea --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini.orig @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/qos.json b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/qos.json new file mode 100644 index 000000000000..d35f614de635 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/qos.json @@ -0,0 +1,166 @@ +{ + "TC_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "MAP_PFC_PRIORITY_TO_QUEUE": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "TC_TO_QUEUE_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "DSCP_TO_TC_MAP": { + "AZURE": { + "0":"0", + "1":"0", + "2":"0", + "3":"3", + "4":"4", + "5":"0", + "6":"0", + "7":"0", + "8":"1", + "9":"0", + "10":"0", + "11":"0", + "12":"0", + "13":"0", + "14":"0", + "15":"0", + "16":"0", + "17":"0", + "18":"0", + "19":"0", + "20":"0", + "21":"0", + "22":"0", + "23":"0", + "24":"0", + "25":"0", + "26":"0", + "27":"0", + "28":"0", + "29":"0", + "30":"0", + "31":"0", + "32":"0", + "33":"0", + "34":"0", + "35":"0", + "36":"0", + "37":"0", + "38":"0", + "39":"0", + "40":"0", + "41":"0", + "42":"0", + "43":"0", + "44":"0", + "45":"0", + "46":"0", + "47":"0", + "48":"0", + "49":"0", + "50":"0", + "51":"0", + "52":"0", + "53":"0", + "54":"0", + "55":"0", + "56":"0", + "57":"0", + "58":"0", + "59":"0", + "60":"0", + "61":"0", + "62":"0", + "63":"0" + } + }, + "SCHEDULER": { + "scheduler.0": { + "type":"DWRR", + "weight": "25" + }, + "scheduler.1": { + "type":"DWRR", + "weight": "30" + }, + "scheduler.2": { + "type":"DWRR", + "weight": "20" + } + }, + "PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { + "AZURE": { + "0": "0", + "1": "1", + "3": "3", + "4": "4" + } + }, + "PORT_QOS_MAP": { + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68": { + "dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", + "tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", + "tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", + "pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", + "pfc_enable": "3,4" + } + }, + "WRED_PROFILE": { + "AZURE_LOSSY": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + }, + "AZURE_LOSSLESS": { + "wred_green_enable":"true", + "wred_yellow_enable":"true", + "ecn":"ecn_all", + "red_max_threshold":"516096", + "red_min_threshold":"516096", + "yellow_max_threshold":"516096", + "yellow_min_threshold":"516096", + "green_max_threshold": "184320", + "green_min_threshold": "184320" + } + }, + "QUEUE": { + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|0": { + "scheduler" : "[SCHEDULER|scheduler.1]" + }, + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|1": { + "scheduler" : "[SCHEDULER|scheduler.2]" + }, + "Ethernet0,Ethernet4,Ethernet8,Ethernet12,Ethernet16,Ethernet20,Ethernet24,Ethernet28,Ethernet32,Ethernet36,Ethernet40,Ethernet44,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124|0-1": { + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSY]" + }, + "Ethernet8,Ethernet2,Ethernet0,Ethernet6,Ethernet4,Ethernet108,Ethernet100,Ethernet104,Ethernet106,Ethernet58,Ethernet126,Ethernet96,Ethernet124,Ethernet122,Ethernet92,Ethernet120,Ethernet50,Ethernet52,Ethernet54,Ethernet56,Ethernet76,Ethernet74,Ethernet18,Ethernet70,Ethernet32,Ethernet72,Ethernet16,Ethernet36,Ethernet78,Ethernet60,Ethernet28,Ethernet62,Ethernet14,Ethernet88,Ethernet118,Ethernet24,Ethernet116,Ethernet82,Ethernet114,Ethernet80,Ethernet112,Ethernet86,Ethernet110,Ethernet84,Ethernet48,Ethernet10,Ethernet44,Ethernet42,Ethernet40,Ethernet64,Ethernet66,Ethernet12,Ethernet46,Ethernet20,Ethernet22,Ethernet68|3-4": { + "scheduler" : "[SCHEDULER|scheduler.0]", + "wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]" + } + } +} + diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai.profile b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai.profile new file mode 100644 index 000000000000..bfbcb1e78f47 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_2700_48x50g_8x100g.xml diff --git a/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml new file mode 100644 index 000000000000..bda7a3e1cc17 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/sai_2700_48x50g_8x100g.xml @@ -0,0 +1,267 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 16 + + + 3 + + + 3221225472 + 2 + + + 3 + 4 + 17 + 1 + 3221225472 + 2 + + + 5 + 4 + 18 + 3 + 3221225472 + 2 + + + 7 + 4 + 19 + 1 + 3221225472 + 2 + + + 9 + 4 + 20 + 3 + 3221225472 + 2 + + + 11 + 4 + 21 + 1 + 3221225472 + 2 + + + 13 + 4 + 22 + 3 + 11534336 + + + 15 + 4 + 23 + 1 + 11534336 + + + 17 + 4 + 24 + 3 + 11534336 + + + 19 + 4 + 25 + 1 + 11534336 + + + 21 + 4 + 26 + 3 + 3221225472 + 2 + + + 23 + 4 + 27 + 1 + 3221225472 + 2> + + + 25 + 4 + 28 + 3 + 3221225472 + 2 + + + 27 + 4 + 29 + 1 + 3221225472 + 2 + + + 29 + 4 + 30 + 3 + 3221225472 + 2 + + + 31 + 4 + 31 + 1 + 3221225472 + 2 + + + 33 + 4 + 14 + 3 + 3221225472 + 2 + + + 35 + 4 + 15 + 1 + 3221225472 + 2 + + + 37 + 4 + 12 + 3 + 3221225472 + 2 + + + 39 + 4 + 13 + 1 + 3221225472 + 2 + + + 41 + 4 + 10 + 3 + 3221225472 + 2 + + + 43 + 4 + 11 + 1 + 3221225472 + 2 + + + 45 + 4 + 8 + 3 + 11534336 + + + 47 + 4 + 9 + 1 + 11534336 + + + 49 + 4 + 6 + 3 + 11534336 + + + 51 + 4 + 7 + 1 + 11534336 + + + 53 + 4 + 4 + 3 + 3221225472 + 2 + + + 55 + 4 + 5 + 1 + 3221225472 + 2 + + + 57 + 4 + 2 + 3 + 3221225472 + 2 + + + 59 + 4 + 3 + 1 + 3221225472 + 2 + + + 61 + 4 + 0 + 3 + 3221225472 + 2 + + + 63 + 4 + 1 + 1 + 3221225472 + 2 + + + + diff --git a/sonic-utilities-tests/sku_create_input/default_sku b/sonic-utilities-tests/sku_create_input/default_sku new file mode 100644 index 000000000000..0209048db975 --- /dev/null +++ b/sonic-utilities-tests/sku_create_input/default_sku @@ -0,0 +1 @@ +ACS-MSN2700 t1 diff --git a/sonic-utilities-tests/sku_create_test.py b/sonic-utilities-tests/sku_create_test.py new file mode 100644 index 000000000000..6106e82e0ce8 --- /dev/null +++ b/sonic-utilities-tests/sku_create_test.py @@ -0,0 +1,74 @@ +import sys +import os +import pytest +import subprocess +import re + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +scripts_path = os.path.join(modules_path, "scripts") +input_path = os.path.join(modules_path, "sonic-utilities-tests/sku_create_input") +sku_def_file = os.path.join(input_path, "Mellanox-SN2700-D48C8.xml") +sku_create_script = os.path.join(scripts_path, "sonic_sku_create.py") +output_file_path = os.path.join(modules_path, "sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8_NEW/port_config.ini") +model_file_path = os.path.join(modules_path, "sonic-utilities-tests/sku_create_input/Mellanox-SN2700-D48C8/port_config.ini") + +sys.path.insert(0, test_path) +sys.path.insert(0, modules_path) + +class TestSkuCreate(object): + @classmethod + def setup_class(cls): + os.environ["PATH"] += os.pathsep + scripts_path + os.environ["UTILITIES_UNIT_TESTING"] = "1" + + def are_file_contents_same(self,fname1,fname2): + #Open the file for reading in text mode (default mode) + f1 = open(fname1) + f2 = open(fname2) + + #Read the first line from the files + f1_line = f1.readline() + f2_line = f2.readline() + + #Loop if either fname1 or fname2 has not reached EOF + while f1_line!='' or f2_line!='': + f1_line = re.sub('[\s+]','',f1_line) + f2_line = re.sub('[\s+]','',f2_line) + + if f1_line!=f2_line: + f1.close() + f2.close() + return False + else: + f1_line = f1.readline() + f2_line = f2.readline() + + f1.close() + f2.close() + return True + + def test_no_param(self): + my_command = sku_create_script + " -f " + sku_def_file + " -d " + input_path + + #Test case execution without stdout + result = subprocess.check_output(my_command,stderr=subprocess.STDOUT,shell=True) + print result + + #Check if the Output file exists + if (os.path.exists(output_file_path)): + print("Output file: ",output_file_path,"exists. SUCCESS!") + else: + pytest.fail("Output file: {} does not exist. FAILURE!".format(output_file_path)) + + #Check if the Output file and the model file have same contents + if self.are_file_contents_same(output_file_path,model_file_path) == True: + print("Output file: ",output_file_path," and model file: ",model_file_path,"contents are same. SUCCESS!") + else: + pytest.fail("Output file: {} and model file: {} contents are not same. FAILURE!".format(output_file_path,model_file_path)) + + @classmethod + def teardown_class(cls): + print("TEARDOWN") + os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1]) + os.environ["UTILITIES_UNIT_TESTING"] = "0"