Skip to content

Commit

Permalink
[DASH] Add support for ENI counters
Browse files Browse the repository at this point in the history
Signed-off-by: Vivek Reddy <vkarri@nvidia.com>
  • Loading branch information
vivekrnv committed Jul 15, 2024
1 parent f96a132 commit 85b4893
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
62 changes: 62 additions & 0 deletions counterpoll/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@
from flow_counter_util.route import exit_if_route_flow_counter_not_support
from swsscommon.swsscommon import ConfigDBConnector
from tabulate import tabulate
from sonic_py_common import device_info

BUFFER_POOL_WATERMARK = "BUFFER_POOL_WATERMARK"
PORT_BUFFER_DROP = "PORT_BUFFER_DROP"
PG_DROP = "PG_DROP"
ACL = "ACL"
ENI = "ENI"
DISABLE = "disable"
ENABLE = "enable"
DEFLT_60_SEC= "default (60000)"
DEFLT_10_SEC= "default (10000)"
DEFLT_1_SEC = "default (1000)"

def is_dpu(db):
""" Check if the device is DPU """
platform_info = device_info.get_platform_info(db)
if platform_info.get('switch_type', '') == 'dpu':
return True
else:
return False


@click.group()
def cli():
""" SONiC Static Counter Poll configurations """
Expand Down Expand Up @@ -126,6 +137,7 @@ def disable():
port_info['FLEX_COUNTER_STATUS'] = DISABLE
configdb.mod_entry("FLEX_COUNTER_TABLE", PORT_BUFFER_DROP, port_info)


# Ingress PG drop packet stat
@cli.group()
@click.pass_context
Expand Down Expand Up @@ -382,6 +394,52 @@ def disable(ctx):
fc_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info)

# ENI counter commands
@cli.group()
@click.pass_context
def eni(ctx):
""" ENI counter commands """
ctx.obj = ConfigDBConnector()
ctx.obj.connect()

@eni.command()
@click.argument('poll_interval', type=click.IntRange(1000, 30000))
@click.pass_context
def interval(ctx, poll_interval):
""" Set eni counter query interval """
if not is_dpu(ctx.obj):
click.echo("ENI counters are not supported on non DPU platforms")
exit(1)

eni_info = {}
if poll_interval is not None:
eni_info['POLL_INTERVAL'] = poll_interval
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", ENI, eni_info)

@eni.command()
@click.pass_context
def enable(ctx):
""" Enable eni counter query """
if not is_dpu(ctx.obj):
click.echo("ENI counters are not supported on non DPU platforms")
exit(1)

eni_info = {}
eni_info['FLEX_COUNTER_STATUS'] = 'enable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", ENI, eni_info)

@eni.command()
@click.pass_context
def disable(ctx):
""" Disable eni counter query """
if not is_dpu(ctx.obj):
click.echo("ENI counters are not supported on non DPU platforms")
exit(1)

eni_info = {}
eni_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", ENI, eni_info)

@cli.command()
def show():
""" Show the counter configuration """
Expand All @@ -399,6 +457,7 @@ def show():
tunnel_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'TUNNEL')
trap_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_TRAP')
route_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_ROUTE')
eni_info = configdb.get_entry('FLEX_COUNTER_TABLE', ENI)

header = ("Type", "Interval (in ms)", "Status")
data = []
Expand Down Expand Up @@ -428,6 +487,9 @@ def show():
data.append(["FLOW_CNT_ROUTE_STAT", route_info.get("POLL_INTERVAL", DEFLT_10_SEC),
route_info.get("FLEX_COUNTER_STATUS", DISABLE)])

if is_dpu(config_db) and eni_info:
data.append(["ENI_STAT", eni_info.get("POLL_INTERVAL", DEFLT_1_SEC), eni_info.get("FLEX_COUNTER_STATUS", DISABLE)])

click.echo(tabulate(data, headers=header, tablefmt="simple", missingval=""))

def _update_config_db_flex_counter_table(status, filename):
Expand Down
61 changes: 61 additions & 0 deletions tests/counterpoll_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import os
import pytest
import mock
import sys
from click.testing import CliRunner
from shutil import copyfile
Expand Down Expand Up @@ -31,6 +32,21 @@
FLOW_CNT_ROUTE_STAT 10000 enable
"""

expected_counterpoll_show_dpu = """Type Interval (in ms) Status
-------------------- ------------------ --------
QUEUE_STAT 10000 enable
PORT_STAT 1000 enable
PORT_BUFFER_DROP 60000 enable
QUEUE_WATERMARK_STAT default (60000) enable
PG_WATERMARK_STAT default (60000) enable
PG_DROP_STAT 10000 enable
ACL 5000 enable
TUNNEL_STAT 3000 enable
FLOW_CNT_TRAP_STAT 10000 enable
FLOW_CNT_ROUTE_STAT 10000 enable
ENI_STAT 1000 enable
"""

class TestCounterpoll(object):
@classmethod
def setup_class(cls):
Expand All @@ -44,6 +60,14 @@ def test_show(self):
print(result.output)
assert result.output == expected_counterpoll_show

@mock.patch('counterpoll.main.device_info.get_platform_info')
def test_show_dpu(self, mock_get_platform_info):
mock_get_platform_info.return_value = {'switch_type': 'dpu'}
runner = CliRunner()
result = runner.invoke(counterpoll.cli.commands["show"], [])
print(result.output)
assert result.output == expected_counterpoll_show_dpu

def test_port_buffer_drop_interval(self):
runner = CliRunner()
result = runner.invoke(counterpoll.cli.commands["port-buffer-drop"].commands["interval"], ["30000"])
Expand Down Expand Up @@ -221,6 +245,43 @@ def test_update_route_counter_interval(self):
assert result.exit_code == 2
assert expected in result.output

@pytest.mark.parametrize("status", ["disable", "enable"])
def test_update_eni_status(self, status):
runner = CliRunner()
db = Db()

result = runner.invoke(counterpoll.cli.commands["eni"].commands[status], [], obj=db.cfgdb)
print(result.exit_code, result.output)
assert result.exit_code == 1
assert result.output == "ENI counters are not supported on non DPU platforms\n"

@pytest.mark.parametrize("status", ["disable", "enable"])
@mock.patch('counterpoll.main.device_info.get_platform_info')
def test_update_eni_status_dpu(self, mock_get_platform_info, status):
mock_get_platform_info.return_value = {'switch_type': 'dpu'}
runner = CliRunner()
db = Db()

result = runner.invoke(counterpoll.cli.commands["eni"].commands[status], [], obj=db.cfgdb)
print(result.exit_code, result.output)
assert result.exit_code == 0

table = db.cfgdb.get_table('FLEX_COUNTER_TABLE')
assert status == table["ENI"]["FLEX_COUNTER_STATUS"]

@mock.patch('counterpoll.main.device_info.get_platform_info')
def test_update_eni_interval(self, mock_get_platform_info):
mock_get_platform_info.return_value = {'switch_type': 'dpu'}
runner = CliRunner()
db = Db()
test_interval = "2000"

result = runner.invoke(counterpoll.cli.commands["eni"].commands["interval"], [test_interval], obj=db.cfgdb)
print(result.exit_code, result.output)
assert result.exit_code == 0

table = db.cfgdb.get_table('FLEX_COUNTER_TABLE')
assert test_interval == table["ENI"]["POLL_INTERVAL"]

@classmethod
def teardown_class(cls):
Expand Down
4 changes: 4 additions & 0 deletions tests/mock_tables/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,10 @@
"POLL_INTERVAL": "10000",
"FLEX_COUNTER_STATUS": "enable"
},
"FLEX_COUNTER_TABLE|ENI": {
"POLL_INTERVAL": "1000",
"FLEX_COUNTER_STATUS": "enable"
},
"PFC_WD|Ethernet0": {
"action": "drop",
"detection_time": "600",
Expand Down

0 comments on commit 85b4893

Please sign in to comment.