|
4 | 4 | import pytest |
5 | 5 | import signal |
6 | 6 | import threading |
| 7 | +import time |
| 8 | +from datetime import datetime |
7 | 9 | from imp import load_source |
8 | 10 | import re |
9 | 11 |
|
@@ -455,3 +457,99 @@ def hset(key, field, value): |
455 | 457 | # Verify current states were updated |
456 | 458 | assert dpu_state_mng.current_dp_state == 'up' |
457 | 459 | 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