Skip to content

Commit eedae8c

Browse files
Merge branch 'sonic-net:master' into graceful-shutdown
2 parents 8762717 + cf87190 commit eedae8c

File tree

9 files changed

+1067
-386
lines changed

9 files changed

+1067
-386
lines changed

sonic-chassisd/scripts/chassisd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,10 @@ class DpuStateManagerTask(ProcessTaskBase):
15941594
update_required = False
15951595
continue
15961596
self.logger.log_info(f"DPU_STATE change detected: operation={op}, key={key}")
1597+
elif key:
1598+
# If there is any change in the non-DPU_STATE table, we need to update the state
1599+
update_required = True
1600+
break
15971601

15981602
if update_required:
15991603
[self.current_dp_state, self.current_cp_state] = self.dpu_state_updater.update_state()

sonic-chassisd/tests/test_dpu_chassisd.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import pytest
55
import signal
66
import threading
7+
import time
8+
from datetime import datetime
79
from imp import load_source
810
import re
911

@@ -455,3 +457,99 @@ def hset(key, field, value):
455457
# Verify current states were updated
456458
assert dpu_state_mng.current_dp_state == 'up'
457459
assert dpu_state_mng.current_cp_state == 'down'
460+
461+
462+
def test_dpu_state_manager_update_required_logic():
463+
"""Test that DpuStateManagerTask correctly sets update_required based on various conditions"""
464+
chassis = MockDpuChassis()
465+
chassis.get_dpu_id = MagicMock(return_value=0)
466+
chassis.get_dataplane_state = MagicMock(return_value=True)
467+
chassis.get_controlplane_state = MagicMock(return_value=True)
468+
469+
chassis_state_db = {}
470+
update_count = 0
471+
472+
def hset(key, field, value):
473+
nonlocal update_count
474+
update_count += 1
475+
if key not in chassis_state_db:
476+
chassis_state_db[key] = {}
477+
chassis_state_db[key][field] = value
478+
479+
# Test case 1: update_required should be True when there are changes in non-DPU_STATE tables
480+
with mock.patch.object(swsscommon.Table, 'hset', side_effect=hset):
481+
# Create mock selectables
482+
mock_selectable_app_db = MagicMock()
483+
mock_selectable_app_db.getDbConnector.return_value.getDbName.return_value = 'APPL_DB'
484+
mock_selectable_app_db.pop.return_value = ('PORT_TABLE_KEY', 'SET', None)
485+
486+
mock_selectable_state_db = MagicMock()
487+
mock_selectable_state_db.getDbConnector.return_value.getDbName.return_value = 'STATE_DB'
488+
mock_selectable_state_db.pop.return_value = None
489+
490+
mock_selectable_chassis_state_db = MagicMock()
491+
mock_selectable_chassis_state_db.getDbConnector.return_value.getDbName.return_value = 'CHASSIS_STATE_DB'
492+
mock_selectable_chassis_state_db.pop.return_value = None
493+
494+
# Mock the SubscriberStateTable constructor to return our mock selectables
495+
with mock.patch.object(swsscommon, 'SubscriberStateTable', side_effect=[
496+
mock_selectable_app_db, # PORT_TABLE
497+
mock_selectable_state_db, # SYSTEM_READY
498+
mock_selectable_chassis_state_db # DPU_STATE
499+
]):
500+
with mock.patch.object(swsscommon.Select, 'select',
501+
side_effect=[(swsscommon.Select.OBJECT, None), KeyboardInterrupt]):
502+
503+
dpu_updater = DpuStateUpdater(SYSLOG_IDENTIFIER, chassis)
504+
dpu_updater._time_now = MagicMock(return_value='Sat Jan 01 12:00:00 AM UTC 2000')
505+
506+
dpu_state_mng = DpuStateManagerTask(SYSLOG_IDENTIFIER, dpu_updater)
507+
dpu_state_mng.current_dp_state = 'up'
508+
dpu_state_mng.current_cp_state = 'up'
509+
510+
dpu_state_mng.task_worker()
511+
512+
# Verify state was updated since update_required should be True
513+
assert update_count > 0
514+
515+
# Reset for test case 2
516+
update_count = 0
517+
chassis_state_db = {}
518+
519+
# Test case 2: update_required should be True when pop returns multiple values
520+
# and one key returns STATE_DB and another CHASSIS_STATE_DB
521+
with mock.patch.object(swsscommon.Table, 'hset', side_effect=hset):
522+
# Create mock selectables with different database names
523+
mock_selectable_app_db = MagicMock()
524+
mock_selectable_app_db.getDbConnector.return_value.getDbName.return_value = 'APPL_DB'
525+
mock_selectable_app_db.pop.return_value = None
526+
527+
mock_selectable_state_db = MagicMock()
528+
mock_selectable_state_db.getDbConnector.return_value.getDbName.return_value = 'STATE_DB'
529+
mock_selectable_state_db.pop.return_value = ('SYSTEM_READY_KEY', 'SET', (('Status', 'UP'), ('Other', 'Value')))
530+
531+
mock_selectable_chassis_state_db = MagicMock()
532+
mock_selectable_chassis_state_db.getDbConnector.return_value.getDbName.return_value = 'CHASSIS_STATE_DB'
533+
mock_selectable_chassis_state_db.pop.return_value = None
534+
535+
# Mock the SubscriberStateTable constructor to return our mock selectables
536+
with mock.patch.object(swsscommon, 'SubscriberStateTable', side_effect=[
537+
mock_selectable_app_db, # PORT_TABLE
538+
mock_selectable_state_db, # SYSTEM_READY
539+
mock_selectable_chassis_state_db # DPU_STATE
540+
]):
541+
with mock.patch.object(swsscommon.Select, 'select',
542+
side_effect=[(swsscommon.Select.OBJECT, None), KeyboardInterrupt]):
543+
544+
dpu_updater = DpuStateUpdater(SYSLOG_IDENTIFIER, chassis)
545+
dpu_updater._time_now = MagicMock(return_value='Sat Jan 01 12:00:00 AM UTC 2000')
546+
547+
dpu_state_mng = DpuStateManagerTask(SYSLOG_IDENTIFIER, dpu_updater)
548+
dpu_state_mng.current_dp_state = 'up'
549+
dpu_state_mng.current_cp_state = 'up'
550+
551+
dpu_state_mng.task_worker()
552+
553+
# Verify state was updated since update_required should be True for multiple values
554+
# even with mixed STATE_DB and CHASSIS_STATE_DB
555+
assert update_count > 0

0 commit comments

Comments
 (0)