@@ -268,7 +268,7 @@ def hset(key, field, value):
268
268
}}
269
269
270
270
271
- def test_dpu_state_manager_specific_key_update ():
271
+ def test_dpu_state_manager_none_result ():
272
272
chassis = MockDpuChassis ()
273
273
chassis .get_dpu_id = MagicMock (return_value = 0 )
274
274
chassis .get_dataplane_state = MagicMock (return_value = True )
@@ -281,8 +281,11 @@ def hset(key, field, value):
281
281
chassis_state_db [key ] = {}
282
282
chassis_state_db [key ][field ] = value
283
283
284
+ def mock_pop ():
285
+ return None
286
+
284
287
with mock .patch .object (swsscommon .Table , 'hset' , side_effect = hset ):
285
- with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' , return_value = ( 'DPU0' , 'SET' , (( 'dpu_control_plane_state' , 'up' ), ( 'dpu_data_plane_state' , 'up' ))) ):
288
+ with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' , side_effect = mock_pop ):
286
289
with mock .patch .object (swsscommon .Select , 'select' ,
287
290
side_effect = [(swsscommon .Select .OBJECT , None ), KeyboardInterrupt ]):
288
291
@@ -292,11 +295,17 @@ def hset(key, field, value):
292
295
dpu_state_mng = DpuStateManagerTask (SYSLOG_IDENTIFIER , dpu_updater )
293
296
dpu_state_mng .task_worker ()
294
297
295
- # Verify no state update occurred since this was our own state update
296
- assert chassis_state_db == {}
298
+ # Verify state was updated even with None result
299
+ assert chassis_state_db == {'DPU0' : {
300
+ 'dpu_data_plane_state' : 'up' ,
301
+ 'dpu_data_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000' ,
302
+ 'dpu_control_plane_state' : 'up' ,
303
+ 'dpu_control_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000'
304
+ }}
297
305
298
306
299
- def test_dpu_state_manager_none_result ():
307
+ def test_dpu_state_manager_state_tracking ():
308
+ """Test that DpuStateManagerTask correctly tracks current states and avoids unnecessary updates"""
300
309
chassis = MockDpuChassis ()
301
310
chassis .get_dpu_id = MagicMock (return_value = 0 )
302
311
chassis .get_dataplane_state = MagicMock (return_value = True )
@@ -309,11 +318,9 @@ def hset(key, field, value):
309
318
chassis_state_db [key ] = {}
310
319
chassis_state_db [key ][field ] = value
311
320
312
- def mock_pop ():
313
- return None
314
-
321
+ # First update - should set initial states
315
322
with mock .patch .object (swsscommon .Table , 'hset' , side_effect = hset ):
316
- with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' , side_effect = mock_pop ):
323
+ with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' , return_value = ( 'DPU0' , 'SET' , None ) ):
317
324
with mock .patch .object (swsscommon .Select , 'select' ,
318
325
side_effect = [(swsscommon .Select .OBJECT , None ), KeyboardInterrupt ]):
319
326
@@ -323,10 +330,128 @@ def mock_pop():
323
330
dpu_state_mng = DpuStateManagerTask (SYSLOG_IDENTIFIER , dpu_updater )
324
331
dpu_state_mng .task_worker ()
325
332
326
- # Verify state was updated even with None result
333
+ # Verify initial state was set
327
334
assert chassis_state_db == {'DPU0' : {
328
335
'dpu_data_plane_state' : 'up' ,
329
336
'dpu_data_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000' ,
330
337
'dpu_control_plane_state' : 'up' ,
331
338
'dpu_control_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000'
332
339
}}
340
+
341
+ # Verify current states are tracked
342
+ assert dpu_state_mng .current_dp_state == 'up'
343
+ assert dpu_state_mng .current_cp_state == 'up'
344
+
345
+
346
+ def test_dpu_state_manager_avoid_duplicate_updates ():
347
+ """Test that DpuStateManagerTask avoids duplicate state updates"""
348
+ chassis = MockDpuChassis ()
349
+ chassis .get_dpu_id = MagicMock (return_value = 0 )
350
+ chassis .get_dataplane_state = MagicMock (return_value = True )
351
+ chassis .get_controlplane_state = MagicMock (return_value = True )
352
+
353
+ chassis_state_db = {}
354
+ update_count = 0
355
+
356
+ def hset (key , field , value ):
357
+ nonlocal update_count
358
+ update_count += 1
359
+ if key not in chassis_state_db :
360
+ chassis_state_db [key ] = {}
361
+ chassis_state_db [key ][field ] = value
362
+
363
+ # Test with same state update
364
+ with mock .patch .object (swsscommon .Table , 'hset' , side_effect = hset ):
365
+ with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' ,
366
+ return_value = ('DPU0' , 'SET' , (('dpu_data_plane_state' , 'up' ), ('dpu_control_plane_state' , 'up' )))):
367
+ with mock .patch .object (swsscommon .Select , 'select' ,
368
+ side_effect = [(swsscommon .Select .OBJECT , None ), (swsscommon .Select .OBJECT , None ), KeyboardInterrupt ]):
369
+
370
+ dpu_updater = DpuStateUpdater (SYSLOG_IDENTIFIER , chassis )
371
+ dpu_updater ._time_now = MagicMock (return_value = 'Sat Jan 01 12:00:00 AM UTC 2000' )
372
+
373
+ dpu_state_mng = DpuStateManagerTask (SYSLOG_IDENTIFIER , dpu_updater )
374
+ dpu_state_mng .current_dp_state = 'up'
375
+ dpu_state_mng .current_cp_state = 'up'
376
+ dpu_state_mng .task_worker ()
377
+
378
+ # Verify no updates occurred since states were unchanged
379
+ assert update_count == 0
380
+
381
+
382
+ def test_dpu_state_manager_different_dpu ():
383
+ """Test that DpuStateManagerTask handles updates for different DPUs correctly"""
384
+ chassis = MockDpuChassis ()
385
+ chassis .get_dpu_id = MagicMock (return_value = 0 )
386
+ chassis .get_dataplane_state = MagicMock (return_value = True )
387
+ chassis .get_controlplane_state = MagicMock (return_value = True )
388
+
389
+ chassis_state_db = {}
390
+ update_count = 0
391
+
392
+ def hset (key , field , value ):
393
+ nonlocal update_count
394
+ update_count += 1
395
+ if key not in chassis_state_db :
396
+ chassis_state_db [key ] = {}
397
+ chassis_state_db [key ][field ] = value
398
+
399
+ # Test with update for different DPU
400
+ with mock .patch .object (swsscommon .Table , 'hset' , side_effect = hset ):
401
+ with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' ,
402
+ return_value = ('DPU1' , 'SET' , (('dpu_data_plane_state' , 'down' ), ('dpu_control_plane_state' , 'down' )))):
403
+ with mock .patch .object (swsscommon .Select , 'select' ,
404
+ side_effect = [(swsscommon .Select .OBJECT , None ), KeyboardInterrupt ]):
405
+
406
+ dpu_updater = DpuStateUpdater (SYSLOG_IDENTIFIER , chassis )
407
+ dpu_updater ._time_now = MagicMock (return_value = 'Sat Jan 01 12:00:00 AM UTC 2000' )
408
+
409
+ dpu_state_mng = DpuStateManagerTask (SYSLOG_IDENTIFIER , dpu_updater )
410
+ dpu_state_mng .current_dp_state = 'up'
411
+ dpu_state_mng .current_cp_state = 'up'
412
+ dpu_state_mng .task_worker ()
413
+
414
+ # Verify no updates occurred since it was for a different DPU
415
+ assert update_count == 0
416
+
417
+
418
+ def test_dpu_state_manager_state_change ():
419
+ """Test that DpuStateManagerTask handles state changes correctly"""
420
+ chassis = MockDpuChassis ()
421
+ chassis .get_dpu_id = MagicMock (return_value = 0 )
422
+ chassis .get_dataplane_state = MagicMock (return_value = True )
423
+ chassis .get_controlplane_state = MagicMock (return_value = False ) # CP state changed to False
424
+
425
+ chassis_state_db = {}
426
+
427
+ def hset (key , field , value ):
428
+ if key not in chassis_state_db :
429
+ chassis_state_db [key ] = {}
430
+ chassis_state_db [key ][field ] = value
431
+
432
+ # Test with state change
433
+ with mock .patch .object (swsscommon .Table , 'hset' , side_effect = hset ):
434
+ with mock .patch .object (swsscommon .SubscriberStateTable , 'pop' ,
435
+ return_value = ('DPU0' , 'SET' , None )):
436
+ with mock .patch .object (swsscommon .Select , 'select' ,
437
+ side_effect = [(swsscommon .Select .OBJECT , None ), KeyboardInterrupt ]):
438
+
439
+ dpu_updater = DpuStateUpdater (SYSLOG_IDENTIFIER , chassis )
440
+ dpu_updater ._time_now = MagicMock (return_value = 'Sat Jan 01 12:00:00 AM UTC 2000' )
441
+
442
+ dpu_state_mng = DpuStateManagerTask (SYSLOG_IDENTIFIER , dpu_updater )
443
+ dpu_state_mng .current_dp_state = 'up'
444
+ dpu_state_mng .current_cp_state = 'up' # Previous state was up
445
+ dpu_state_mng .task_worker ()
446
+
447
+ # Verify state was updated since control plane state changed
448
+ assert chassis_state_db == {'DPU0' : {
449
+ 'dpu_data_plane_state' : 'up' ,
450
+ 'dpu_data_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000' ,
451
+ 'dpu_control_plane_state' : 'down' , # Changed to down
452
+ 'dpu_control_plane_time' : 'Sat Jan 01 12:00:00 AM UTC 2000'
453
+ }}
454
+
455
+ # Verify current states were updated
456
+ assert dpu_state_mng .current_dp_state == 'up'
457
+ assert dpu_state_mng .current_cp_state == 'down'
0 commit comments