Skip to content

Commit

Permalink
[Multi-asic] Enhanced Feature Table configuration for multi-asic plat…
Browse files Browse the repository at this point in the history
…forms (sonic-net#1152)

Enhanced Feature Table configuration for multi-asic platforms
to programmed for all config db's.
  • Loading branch information
abdosi authored Dec 17, 2020
1 parent 155f6d5 commit 9419627
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 12 deletions.
32 changes: 24 additions & 8 deletions config/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@ def feature():
@pass_db
def feature_state(db, name, state):
"""Enable/disable a feature"""
entry_data = db.cfgdb.get_entry('FEATURE', name)
entry_data_set = set()

if not entry_data:
click.echo("Feature '{}' doesn't exist".format(name))
for ns, cfgdb in db.cfgdb_clients.items():
entry_data = cfgdb.get_entry('FEATURE', name)
if not entry_data:
click.echo("Feature '{}' doesn't exist".format(name))
sys.exit(1)
entry_data_set.add(entry_data['state'])

if len(entry_data_set) > 1:
click.echo("Feature '{}' state is not consistent across namespaces".format(name))
sys.exit(1)

if entry_data['state'] == "always_enabled":
click.echo("Feature '{}' state is always enabled and can not be modified".format(name))
return

db.cfgdb.mod_entry('FEATURE', name, {'state': state})
for ns, cfgdb in db.cfgdb_clients.items():
cfgdb.mod_entry('FEATURE', name, {'state': state})

#
# 'autorestart' command ('config feature autorestart ...')
Expand All @@ -41,14 +49,22 @@ def feature_state(db, name, state):
@pass_db
def feature_autorestart(db, name, autorestart):
"""Enable/disable autorestart of a feature"""
entry_data = db.cfgdb.get_entry('FEATURE', name)
entry_data_set = set()

for ns, cfgdb in db.cfgdb_clients.items():
entry_data = cfgdb.get_entry('FEATURE', name)
if not entry_data:
click.echo("Feature '{}' doesn't exist".format(name))
sys.exit(1)
entry_data_set.add(entry_data['auto_restart'])

if not entry_data:
click.echo("Feature '{}' doesn't exist".format(name))
if len(entry_data_set) > 1:
click.echo("Feature '{}' auto-restart is not consistent across namespaces".format(name))
sys.exit(1)

if entry_data['auto_restart'] == "always_enabled":
click.echo("Feature '{}' auto-restart is always enabled and can not be modified".format(name))
return

db.cfgdb.mod_entry('FEATURE', name, {'auto_restart': autorestart})
for ns, cfgdb in db.cfgdb_clients.items():
cfgdb.mod_entry('FEATURE', name, {'auto_restart': autorestart})
2 changes: 2 additions & 0 deletions tests/crm_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import sys
from importlib import reload

from click.testing import CliRunner
import crm.main as crm
Expand Down Expand Up @@ -1298,3 +1299,4 @@ def teardown_class(cls):
os.environ["UTILITIES_UNIT_TESTING"] = "0"
os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = ""
from .mock_tables import mock_single_asic
reload(mock_single_asic)
107 changes: 107 additions & 0 deletions tests/feature_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from importlib import reload

from click.testing import CliRunner

from utilities_common.db import Db
Expand Down Expand Up @@ -76,6 +78,12 @@
--------- --------------
database always_enabled
"""
config_feature_bgp_inconsistent_state_output="""\
Feature 'bgp' state is not consistent across namespaces
"""
config_feature_bgp_inconsistent_autorestart_output="""\
Feature 'bgp' auto-restart is not consistent across namespaces
"""

class TestFeature(object):
@classmethod
Expand Down Expand Up @@ -217,3 +225,102 @@ def test_config_unknown_feature(self, get_cmd_module):
@classmethod
def teardown_class(cls):
print("TEARDOWN")

class TestFeatureMultiAsic(object):
@classmethod
def setup_class(cls):
print("SETUP")

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)
dbconnector.load_namespace_config()
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["feature"].commands["state"], ["bgp", "disabled"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 1
assert result.output == config_feature_bgp_inconsistent_state_output
result = runner.invoke(config.config.commands["feature"].commands["state"], ["bgp", "enabled"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 1
assert result.output == config_feature_bgp_inconsistent_state_output

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)
dbconnector.load_namespace_config()
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["feature"].commands["autorestart"], ["bgp", "disabled"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 1
assert result.output == config_feature_bgp_inconsistent_autorestart_output
result = runner.invoke(config.config.commands["feature"].commands["autorestart"], ["bgp", "enabled"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 1
assert result.output == config_feature_bgp_inconsistent_autorestart_output

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)
dbconnector.load_namespace_config()
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["feature"].commands["state"], ["bgp", "disabled"], obj=db)
print(result.exit_code)
assert result.exit_code == 0
result = runner.invoke(show.cli.commands["feature"].commands["status"], ["bgp"], obj=db)
print(result.output)
assert result.exit_code == 0
assert result.output == show_feature_bgp_disabled_status_output
result = runner.invoke(config.config.commands["feature"].commands["state"], ["bgp", "enabled"], obj=db)
print(result.exit_code)
print(result.output)
assert result.exit_code == 0
result = runner.invoke(show.cli.commands["feature"].commands["status"], ["bgp"], obj=db)
print(result.output)
assert result.exit_code == 0
assert result.output == show_feature_bgp_status_output

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)
dbconnector.load_namespace_config()
(config, show) = get_cmd_module
db = Db()
runner = CliRunner()
result = runner.invoke(config.config.commands["feature"].commands["autorestart"], ["bgp", "disabled"], obj=db)
print(result.exit_code)
assert result.exit_code == 0
result = runner.invoke(show.cli.commands["feature"].commands["autorestart"], ["bgp"], obj=db)
print(result.output)
print(result.exit_code)
assert result.exit_code == 0
assert result.output == show_feature_bgp_disabled_autorestart_output
result = runner.invoke(config.config.commands["feature"].commands["autorestart"], ["bgp", "enabled"], obj=db)
print(result.exit_code)
assert result.exit_code == 0
result = runner.invoke(show.cli.commands["feature"].commands["autorestart"], ["bgp"], obj=db)
print(result.output)
print(result.exit_code)
assert result.exit_code == 0
assert result.output == show_feature_bgp_autorestart_output


@classmethod
def teardown_class(cls):
print("TEARDOWN")
from .mock_tables import mock_single_asic
reload(mock_single_asic)
8 changes: 4 additions & 4 deletions tests/ip_show_routes_multi_asic_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from importlib import reload

import pytest

Expand All @@ -16,6 +17,7 @@ def setup_class(cls):
os.environ["UTILITIES_UNIT_TESTING"] = "2"
os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = "multi_asic"
from .mock_tables import mock_multi_asic_3_asics
reload(mock_multi_asic_3_asics)
from .mock_tables import dbconnector
dbconnector.load_namespace_config()

Expand Down Expand Up @@ -224,7 +226,5 @@ def teardown_class(cls):
os.environ["PATH"] = os.pathsep.join(os.environ["PATH"].split(os.pathsep)[:-1])
os.environ["UTILITIES_UNIT_TESTING"] = "0"
os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] = ""
import imp
from sonic_py_common import multi_asic
imp.reload(multi_asic)
import mock_tables.dbconnector
from .mock_tables import mock_single_asic
reload(mock_single_asic)
5 changes: 5 additions & 0 deletions tests/mock_tables/asic0/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,10 @@
},
"PEER_SWITCH|sonic" : {
"address_ipv4": "10.2.2.2"
},
"FEATURE|bgp": {
"state": "enabled",
"auto_restart": "enabled",
"high_mem_alert": "disabled"
}
}
5 changes: 5 additions & 0 deletions tests/mock_tables/asic1/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,10 @@
},
"PEER_SWITCH|sonic" : {
"address_ipv4": "10.2.2.2"
},
"FEATURE|bgp": {
"state": "enabled",
"auto_restart": "enabled",
"high_mem_alert": "disabled"
}
}
5 changes: 5 additions & 0 deletions tests/mock_tables/asic2/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,10 @@
"PFC_WD|GLOBAL": {
"BIG_RED_SWITCH": "enable",
"POLL_INTERVAL": "199"
},
"FEATURE|bgp": {
"state": "disabled",
"auto_restart": "disabled",
"high_mem_alert": "disabled"
}
}

0 comments on commit 9419627

Please sign in to comment.