Skip to content

Commit 1213d61

Browse files
[thermal_manager_base] Add a stop function to thermal manager (sonic-net#187)
Add a stop function to thermal manager. Allow thermalctld to call the stop function to stop run_policy function fast
1 parent a95834b commit 1213d61

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

sonic_platform_base/sonic_thermal_control/thermal_manager_base.py

+14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class ThermalManagerBase(object):
2525

2626
_run_thermal_algorithm_at_boot_up = None
2727

28+
_running = True
29+
2830
@classmethod
2931
def initialize(cls):
3032
"""
@@ -43,6 +45,14 @@ def deinitialize(cls):
4345
"""
4446
pass
4547

48+
@classmethod
49+
def stop(cls):
50+
"""
51+
Stop thermal manager.
52+
:return:
53+
"""
54+
cls._running = False
55+
4656
@classmethod
4757
def start_thermal_control_algorithm(cls):
4858
"""
@@ -169,6 +179,8 @@ def run_policy(cls, chassis):
169179
cls._collect_thermal_information(chassis)
170180

171181
for policy in cls._policy_dict.values():
182+
if not cls._running:
183+
return
172184
if policy.is_match(cls._thermal_info_dict):
173185
policy.do_action(cls._thermal_info_dict)
174186

@@ -180,6 +192,8 @@ def _collect_thermal_information(cls, chassis):
180192
:return:
181193
"""
182194
for thermal_info in cls._thermal_info_dict.values():
195+
if not cls._running:
196+
return
183197
thermal_info.collect(chassis)
184198

185199
@classmethod

tests/thermal_manager_test.py

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import os
2+
import sys
3+
4+
# TODO: Clean this up once we no longer need to support Python 2
5+
if sys.version_info.major == 3:
6+
from unittest import mock
7+
else:
8+
import mock
9+
10+
from sonic_platform_base.sonic_thermal_control import thermal_manager_base as tmb
11+
from sonic_platform_base.sonic_thermal_control import thermal_info_base
12+
from sonic_platform_base.sonic_thermal_control import thermal_action_base
13+
from sonic_platform_base.sonic_thermal_control import thermal_condition_base
14+
from sonic_platform_base.sonic_thermal_control import thermal_json_object
15+
16+
17+
@thermal_json_object.thermal_json_object('some_info')
18+
class MockThermalInfo(thermal_info_base.ThermalPolicyInfoBase):
19+
pass
20+
21+
22+
@thermal_json_object.thermal_json_object('action1')
23+
class MockThermalAction1(thermal_action_base.ThermalPolicyActionBase):
24+
def load_from_json(self, json_obj):
25+
self.speed = int(json_obj['speed'])
26+
27+
28+
@thermal_json_object.thermal_json_object('action2')
29+
class MockThermalAction2(thermal_action_base.ThermalPolicyActionBase):
30+
def load_from_json(self, json_obj):
31+
self.enable = bool(json_obj['enable'])
32+
33+
34+
@thermal_json_object.thermal_json_object('condition1')
35+
class MockThermalCondition1(thermal_condition_base.ThermalPolicyConditionBase):
36+
pass
37+
38+
39+
@thermal_json_object.thermal_json_object('condition2')
40+
class MockThermalCondition2(thermal_condition_base.ThermalPolicyConditionBase):
41+
pass
42+
43+
44+
class MockChassis:
45+
pass
46+
47+
48+
class TestThermalManagerBase:
49+
@classmethod
50+
def setup_class(cls):
51+
tests_dir = os.path.dirname(os.path.abspath(__file__))
52+
tmb.ThermalManagerBase.load(os.path.join(tests_dir, 'thermal_policy.json'))
53+
54+
def test_load_policy(self):
55+
assert tmb.ThermalManagerBase._fan_speed_when_suspend == 60
56+
assert tmb.ThermalManagerBase._run_thermal_algorithm_at_boot_up
57+
58+
assert 'some_info' in tmb.ThermalManagerBase._thermal_info_dict
59+
some_info = tmb.ThermalManagerBase._thermal_info_dict['some_info']
60+
assert isinstance(some_info, MockThermalInfo)
61+
62+
assert 'policy1' in tmb.ThermalManagerBase._policy_dict
63+
assert 'policy2' in tmb.ThermalManagerBase._policy_dict
64+
policy1 = tmb.ThermalManagerBase._policy_dict['policy1']
65+
assert MockThermalCondition1 in policy1.conditions
66+
assert isinstance(policy1.conditions[MockThermalCondition1], MockThermalCondition1)
67+
assert MockThermalAction1 in policy1.actions
68+
assert isinstance(policy1.actions[MockThermalAction1], MockThermalAction1)
69+
policy2 = tmb.ThermalManagerBase._policy_dict['policy2']
70+
assert MockThermalCondition2 in policy2.conditions
71+
assert isinstance(policy2.conditions[MockThermalCondition2], MockThermalCondition2)
72+
assert MockThermalAction2 in policy2.actions
73+
assert isinstance(policy2.actions[MockThermalAction2], MockThermalAction2)
74+
75+
def test_run_policy(self):
76+
MockThermalInfo.collect = mock.MagicMock()
77+
MockThermalCondition1.is_match = mock.MagicMock(return_value=False)
78+
MockThermalCondition2.is_match = mock.MagicMock(return_value=True)
79+
MockThermalAction1.execute = mock.MagicMock()
80+
MockThermalAction2.execute = mock.MagicMock()
81+
82+
chassis = MockChassis()
83+
tmb.ThermalManagerBase.run_policy(chassis)
84+
assert MockThermalInfo.collect.call_count == 1
85+
assert MockThermalCondition1.is_match.call_count == 1
86+
assert MockThermalCondition2.is_match.call_count == 1
87+
assert MockThermalAction1.execute.call_count == 0
88+
assert MockThermalAction2.execute.call_count == 1
89+
90+
MockThermalInfo.collect.reset_mock()
91+
MockThermalCondition1.is_match.reset_mock()
92+
MockThermalCondition2.is_match.reset_mock()
93+
tmb.ThermalManagerBase.stop()
94+
tmb.ThermalManagerBase.run_policy(chassis)
95+
assert MockThermalInfo.collect.call_count == 0
96+
assert MockThermalCondition1.is_match.call_count == 0
97+
assert MockThermalCondition2.is_match.call_count == 0
98+
99+
tmb.ThermalManagerBase._collect_thermal_information = mock.MagicMock()
100+
tmb.ThermalManagerBase.run_policy(chassis)
101+
assert MockThermalCondition1.is_match.call_count == 0
102+
assert MockThermalCondition2.is_match.call_count == 0

tests/thermal_policy.json

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"thermal_control_algorithm": {
3+
"run_at_boot_up": "true",
4+
"fan_speed_when_suspend": "60"
5+
},
6+
"info_types": [
7+
{
8+
"type": "some_info"
9+
}
10+
],
11+
"policies": [
12+
{
13+
"name": "policy1",
14+
"conditions": [
15+
{
16+
"type": "condition1"
17+
}
18+
],
19+
"actions": [
20+
{
21+
"type": "action1",
22+
"speed": "100"
23+
}
24+
]
25+
},
26+
{
27+
"name": "policy2",
28+
"conditions": [
29+
{
30+
"type": "condition2"
31+
}
32+
],
33+
"actions": [
34+
{
35+
"type": "action2",
36+
"enable": "False"
37+
}
38+
]
39+
}
40+
]
41+
}

0 commit comments

Comments
 (0)