Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mellanox] Add validation for thermal policy #78

Merged
merged 2 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ def load_from_json(self, json_obj):
"""
pass

def __eq__(self, other):
"""
Compare input object with this object, return True if equal. Subclass should override this
if necessary.
:param other: Object to compare with.
:return: True if equal else False
"""
return self.__class__ == other.__class__

@classmethod
def register_concrete_type(cls, type_name, object_type):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def _load_policy(cls, json_policy):

policy = ThermalPolicy()
policy.load_from_json(json_policy)
policy.validate_duplicate_policy(cls._policy_dict.values())
cls._policy_dict[name] = policy
else:
raise Exception('{} not found in policy'.format(cls.JSON_FIELD_POLICY_NAME))
Expand Down
34 changes: 28 additions & 6 deletions sonic_platform_base/sonic_thermal_control/thermal_policy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .thermal_json_object import ThermalJsonObject
from collections import OrderedDict


class ThermalPolicy(object):
Expand All @@ -15,10 +16,10 @@ def __init__(self):
self.name = None

# Conditions load from JSON policy file
self.conditions = []
self.conditions = OrderedDict()

# Actions load from JSON policy file
self.actions = []
self.actions = OrderedDict()

def load_from_json(self, json_obj):
"""
Expand All @@ -32,16 +33,23 @@ def load_from_json(self, json_obj):
if self.JSON_FIELD_CONDITIONS in json_obj:
for json_condition in json_obj[self.JSON_FIELD_CONDITIONS]:
cond_type = ThermalJsonObject.get_type(json_condition)
if cond_type in self.conditions:
raise Exception('Duplicate thermal condition type detected in policy [{}]!'.format(self.name))
cond_obj = cond_type()
cond_obj.load_from_json(json_condition)
self.conditions.append(cond_obj)
self.conditions[cond_type] = cond_obj

if self.JSON_FIELD_ACTIONS in json_obj:
for json_action in json_obj[self.JSON_FIELD_ACTIONS]:
action_type = ThermalJsonObject.get_type(json_action)
if action_type in self.actions:
raise Exception('Duplicate thermal action type detected in policy [{}]!'.format(self.name))
action_obj = action_type()
action_obj.load_from_json(json_action)
self.actions.append(action_obj)
self.actions[action_type] = action_obj

if not len(self.conditions) or not len(self.actions):
raise Exception('A policy requires at least 1 action and 1 condition')
else:
raise Exception('name field not found in policy')

Expand All @@ -51,7 +59,7 @@ def is_match(self, thermal_info_dict):
:param thermal_info_dict: A dictionary stores all thermal information.
:return: True if all conditions matches else False.
"""
for condition in self.conditions:
for condition in self.conditions.values():
if not condition.is_match(thermal_info_dict):
return False

Expand All @@ -63,5 +71,19 @@ def do_action(self, thermal_info_dict):
:param thermal_info_dict: A dictionary stores all thermal information.
:return:
"""
for action in self.actions:
for action in self.actions.values():
action.execute(thermal_info_dict)

def validate_duplicate_policy(self, policies):
"""
Detect this policy with existing policies, if a policy with same conditions exists, raise Exception.
:param policies: existing policies.
:return:
"""
for policy in policies:
if len(policy.conditions) != len(self.conditions):
continue

for cond_type, value in policy.conditions.items():
if cond_type in self.conditions and policy.conditions[cond_type] == self.conditions[cond_type]:
raise Exception('Policy [{}] and policy [{}] have duplicate conditions'.format(policy.name, self.name))