Skip to content
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
56 changes: 39 additions & 17 deletions sonic-thermalctld/scripts/thermalctld
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

from enum import Enum, auto
import argparse
import signal
import sys
import threading
Expand Down Expand Up @@ -742,23 +743,24 @@ class TemperatureUpdater(logger.Logger):


class ThermalMonitor(ProcessTaskBase):
# Initial update interval
INITIAL_INTERVAL = 5

# Update interval value
UPDATE_INTERVAL = 60

# Update elapse threshold. If update used time is larger than the value, generate a warning log.
UPDATE_ELAPSED_THRESHOLD = 30

def __init__(self, chassis):
def __init__(
self, chassis, initial_interval, update_interval, update_elapsed_threshold
):
"""
Initializer for ThermalMonitor
:param chassis: Object representing a platform chassis
"""
super(ThermalMonitor, self).__init__()

self.wait_time = self.INITIAL_INTERVAL
# Initial update interval
self.initial_interval = initial_interval
# Update interval value
self.update_interval = update_interval
# Update elapse threshold. If update used time is larger than the value, generate a warning log
self.update_elapsed_threshold = update_elapsed_threshold

self.wait_time = self.initial_interval

# TODO: Refactor to eliminate the need for this Logger instance
self.logger = logger.Logger(SYSLOG_IDENTIFIER)
Expand All @@ -774,12 +776,12 @@ class ThermalMonitor(ProcessTaskBase):
self.fan_updater.update()
self.temperature_updater.update()
elapsed = time.time() - begin
if elapsed < self.UPDATE_INTERVAL:
self.wait_time = self.UPDATE_INTERVAL - elapsed
if elapsed < self.update_interval:
self.wait_time = self.update_interval - elapsed
else:
self.wait_time = self.INITIAL_INTERVAL
self.wait_time = self.initial_interval

if elapsed > self.UPDATE_ELAPSED_THRESHOLD:
if elapsed > self.update_elapsed_threshold:
self.logger.log_warning('Update fan and temperature status took {} seconds, '
'there might be performance risk'.format(elapsed))

Expand Down Expand Up @@ -808,7 +810,12 @@ class ThermalControlDaemon(daemon_base.DaemonBase):

POLICY_FILE = '/usr/share/sonic/platform/thermal_policy.json'

def __init__(self):
def __init__(
self,
thermal_monitor_initial_interval,
thermal_monitor_update_interval,
thermal_monitor_update_elapsed_threshold,
):
"""
Initializer of ThermalControlDaemon
"""
Expand All @@ -823,7 +830,12 @@ class ThermalControlDaemon(daemon_base.DaemonBase):

self.chassis = sonic_platform.platform.Platform().get_chassis()

self.thermal_monitor = ThermalMonitor(self.chassis)
self.thermal_monitor = ThermalMonitor(
self.chassis,
thermal_monitor_initial_interval,
thermal_monitor_update_interval,
thermal_monitor_update_elapsed_threshold
)
self.thermal_monitor.task_run()

self.thermal_manager = None
Expand Down Expand Up @@ -912,7 +924,17 @@ class ThermalControlDaemon(daemon_base.DaemonBase):
# Main =========================================================================
#
def main():
thermal_control = ThermalControlDaemon()
parser = argparse.ArgumentParser()
parser.add_argument('--thermal-monitor-initial-interval', type=int, default=5)
parser.add_argument('--thermal-monitor-update-interval', type=int, default=60)
parser.add_argument('--thermal-monitor-update-elapsed-threshold', type=int, default=30)
args = parser.parse_args()

thermal_control = ThermalControlDaemon(
args.thermal_monitor_initial_interval,
args.thermal_monitor_update_interval,
args.thermal_monitor_update_elapsed_threshold
)

thermal_control.log_info("Starting up...")

Expand Down
14 changes: 7 additions & 7 deletions sonic-thermalctld/tests/test_thermalctld.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ class TestThermalMonitor(object):
"""
def test_main(self):
mock_chassis = MockChassis()
thermal_monitor = thermalctld.ThermalMonitor(mock_chassis)
thermal_monitor = thermalctld.ThermalMonitor(mock_chassis, 5, 60, 30)
thermal_monitor.fan_updater.update = mock.MagicMock()
thermal_monitor.temperature_updater.update = mock.MagicMock()

Expand Down Expand Up @@ -680,7 +680,7 @@ def test_updater_thermal_check_min_max():

def test_signal_handler():
# Test SIGHUP
daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.set = mock.MagicMock()
daemon_thermalctld.log_info = mock.MagicMock()
daemon_thermalctld.log_warning = mock.MagicMock()
Expand All @@ -695,7 +695,7 @@ def test_signal_handler():
assert thermalctld.exit_code == thermalctld.ERR_UNKNOWN

# Test SIGINT
daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.set = mock.MagicMock()
daemon_thermalctld.log_info = mock.MagicMock()
daemon_thermalctld.log_warning = mock.MagicMock()
Expand All @@ -712,7 +712,7 @@ def test_signal_handler():

# Test SIGTERM
thermalctld.exit_code = thermalctld.ERR_UNKNOWN
daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.set = mock.MagicMock()
daemon_thermalctld.log_info = mock.MagicMock()
daemon_thermalctld.log_warning = mock.MagicMock()
Expand All @@ -729,7 +729,7 @@ def test_signal_handler():

# Test an unhandled signal
thermalctld.exit_code = thermalctld.ERR_UNKNOWN
daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.set = mock.MagicMock()
daemon_thermalctld.log_info = mock.MagicMock()
daemon_thermalctld.log_warning = mock.MagicMock()
Expand All @@ -745,14 +745,14 @@ def test_signal_handler():


def test_daemon_run():
daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.wait = mock.MagicMock(return_value=True)
daemon_thermalctld.thermal_manager.get_interval = mock.MagicMock(return_value=60)
ret = daemon_thermalctld.run()
daemon_thermalctld.deinit() # Deinit becuase the test will hang if we assert
assert ret is False

daemon_thermalctld = thermalctld.ThermalControlDaemon()
daemon_thermalctld = thermalctld.ThermalControlDaemon(5, 60, 30)
daemon_thermalctld.stop_event.wait = mock.MagicMock(return_value=False)
daemon_thermalctld.thermal_manager.get_interval = mock.MagicMock(return_value=60)
ret = daemon_thermalctld.run()
Expand Down