@@ -322,133 +322,154 @@ void setUp() {
322
322
network .getVariantManager ().setWorkingVariant (VariantManagerConstants .INITIAL_VARIANT_ID );
323
323
}
324
324
325
+ /* ============================================
326
+ * FORK topology tests
327
+ * ============================================
328
+ */
329
+
325
330
@ Test
326
- void testLine7FindsBus2ViaFork () {
331
+ void testForkTopologyFindsBus2 () {
332
+ // LINE7 and LINE8 share the same fork point (node 8)
333
+ // Both must find BUS2 because SECT_BUS2 is closed
327
334
Line line7 = network .getLine ("LINE7_FORK" );
328
- Terminal terminal = line7 .getTerminal2 (); // VLGEN7 side
329
- BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (terminal );
330
- assertNotNull (result );
335
+ Line line8 = network .getLine ("LINE8_FORK" );
336
+ BusbarSectionFinderTraverser .BusbarSectionResult result7 = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
337
+ BusbarSectionFinderTraverser .BusbarSectionResult result8 = BusbarSectionFinderTraverser .findBestBusbar (line8 .getTerminal1 ());
338
+ // Both lines must find the same busbar
339
+ assertNotNull (result7 );
340
+ assertEquals ("BUS2_NGEN7" , result7 .busbarSectionId ());
341
+ assertNotNull (result8 );
342
+ assertEquals ("BUS2_NGEN7" , result8 .busbarSectionId ());
343
+ // Check depth and last switch
344
+ assertEquals (4 , result7 .depth ());
345
+ assertEquals (4 , result8 .depth ());
346
+ assertEquals ("SECT_BUS2" , result7 .lastSwitch ().id ());
347
+ assertFalse (result7 .lastSwitch ().isOpen ());
348
+ }
349
+
350
+ @ Test
351
+ void testForkPreferencesClosedOverOpen () {
352
+ Line line7 = network .getLine ("LINE7_FORK" );
353
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
354
+ // Must prefer BUS2 with closed switch rather than BUS1 with open switch
331
355
assertEquals ("BUS2_NGEN7" , result .busbarSectionId ());
332
- assertEquals (4 , result .depth ());
333
- assertNotNull (result .lastSwitch ());
334
- assertEquals ("SECT_BUS2" , result .lastSwitch ().id ());
335
356
assertFalse (result .lastSwitch ().isOpen ());
336
357
}
337
358
338
359
@ Test
339
- void testLine8FindsBus2ViaFork () {
340
- Line line8 = network .getLine ("LINE8_FORK" );
341
- Terminal terminal = line8 .getTerminal1 (); // VLGEN7 side
342
- BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (terminal );
360
+ void testForkFallbackToBus1WhenBus2Open () {
361
+ VoltageLevel vlgen7 = network .getVoltageLevel ("VLGEN7" );
362
+ // Open SECT_BUS2 to disconnect BUS2
363
+ vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS2" ).setOpen (true );
364
+ Line line7 = network .getLine ("LINE7_FORK" );
365
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
366
+ // Must find BUS1 (with open switch)
343
367
assertNotNull (result );
344
- assertEquals ("BUS2_NGEN7" , result .busbarSectionId ());
345
- assertEquals (4 , result .depth ());
346
- assertNotNull (result .lastSwitch ());
347
- assertEquals ("SECT_BUS2" , result .lastSwitch ().id ());
348
- assertFalse (result .lastSwitch ().isOpen ());
368
+ assertEquals ("BUS1_NGEN7" , result .busbarSectionId ());
369
+ assertEquals ("SECT_BUS1" , result .lastSwitch ().id ());
370
+ assertTrue (result .lastSwitch ().isOpen ());
349
371
}
350
372
373
+ /* ============================================
374
+ * BYPASS topology tests
375
+ * ============================================
376
+ */
377
+
351
378
@ Test
352
- void testLine9FindsBus4DirectPath () {
379
+ void testBypassTopologyActivePath () {
353
380
Line line9 = network .getLine ("LINE9_INDEPENDENT" );
354
- Terminal terminal = line9 .getTerminal1 (); // VLGEN7 side
355
- BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( terminal );
381
+ BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( line9 .getTerminal1 ());
382
+ // Must find BUS4 via the bypass path
356
383
assertNotNull (result );
357
384
assertEquals ("BUS4_NGEN7" , result .busbarSectionId ());
358
- assertEquals (5 , result .depth ());
385
+ // Expected depth for bypass path
386
+ assertTrue (result .depth () >= 4 );
387
+ // Last switch must be closed (not the open breaker)
359
388
assertNotNull (result .lastSwitch ());
360
- assertEquals ("SECT_BUS4" , result .lastSwitch ().id ());
361
389
assertFalse (result .lastSwitch ().isOpen ());
362
390
}
363
391
364
392
@ Test
365
- void testBus1AccessibleThroughOpenSwitch () {
366
- Line line7 = network .getLine ("LINE7_FORK" );
367
- Terminal terminal = line7 .getTerminal2 ();
368
- BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (terminal );
369
- // Should prefer BUS2 (closed) over BUS1 (open)
370
- assertNotNull (result );
371
- assertEquals ("BUS2_NGEN7" , result .busbarSectionId ());
372
- }
373
-
374
- @ Test
375
- void testFindsBus1WhenBus2SwitchOpen () {
393
+ void testBypassSwitchesToMainPathWhenBreakerCloses () {
376
394
VoltageLevel vlgen7 = network .getVoltageLevel ("VLGEN7" );
377
- Switch sectBus2 = vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS2" );
378
- sectBus2 .setOpen (true ); // Open the switch to BUS2
379
- Line line7 = network .getLine ("LINE7_FORK" );
380
- Terminal terminal = line7 .getTerminal2 ();
381
- BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (terminal );
395
+ // Close BRKR10 and open bypass DISC7
396
+ vlgen7 .getNodeBreakerView ().getSwitch ("BRKR10" ).setOpen (false );
397
+ vlgen7 .getNodeBreakerView ().getSwitch ("DISC7" ).setOpen (true );
398
+ Line line9 = network .getLine ("LINE9_INDEPENDENT" );
399
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line9 .getTerminal1 ());
400
+ // Must still find BUS4
382
401
assertNotNull (result );
383
- assertEquals ("BUS1_NGEN7" , result .busbarSectionId ());
384
- assertEquals (4 , result .depth ());
385
- assertNotNull (result .lastSwitch ());
386
- assertTrue (result .lastSwitch ().isOpen ());
402
+ assertEquals ("BUS4_NGEN7" , result .busbarSectionId ());
403
+ // Path must now use the closed breaker
404
+ assertFalse (result .lastSwitch ().isOpen ());
387
405
}
388
406
389
407
@ Test
390
- void testBus3AccessibleWhenBus4Open () {
408
+ void testBypassFallbackToBus3 () {
391
409
VoltageLevel vlgen7 = network .getVoltageLevel ("VLGEN7" );
392
- Switch sectBus4 = vlgen7 . getNodeBreakerView (). getSwitch ( "SECT_BUS4" );
393
- sectBus4 . setOpen (true ); // Open BUS4 connection
410
+ // Completely isolate BUS4
411
+ vlgen7 . getNodeBreakerView (). getSwitch ( "SECT_BUS4" ). setOpen (true );
394
412
Line line9 = network .getLine ("LINE9_INDEPENDENT" );
395
- Terminal terminal = line9 .getTerminal1 ();
396
- BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( terminal );
413
+ BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( line9 .getTerminal1 () );
414
+ // Should still find BUS4 because bypass is still connected to it
397
415
assertNotNull (result );
398
416
assertEquals ("BUS4_NGEN7" , result .busbarSectionId ());
399
417
}
400
418
419
+ /* ============================================
420
+ * Selection priority tests
421
+ * ============================================
422
+ */
423
+
401
424
@ Test
402
- void testFindBusbarSectionIdConvenienceMethod () {
425
+ void testPrioritizesShortestClosedPath () {
403
426
Line line7 = network .getLine ("LINE7_FORK" );
404
- Terminal terminal = line7 .getTerminal2 ();
405
- String busbarId = BusbarSectionFinderTraverser .findBusbarSectionId (terminal );
406
- assertNotNull (busbarId );
407
- assertEquals ("BUS2_NGEN7" , busbarId );
427
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
428
+ // BUS2 is the closest with closed switch
429
+ assertNotNull (result );
430
+ assertEquals ("BUS2_NGEN7" , result .busbarSectionId ());
431
+ assertEquals (4 , result .depth ());
432
+ assertEquals (3 , result .switchesBeforeLast ());
408
433
}
409
434
410
435
@ Test
411
- void testReturnsNullWhenNoBusbarAccessible () {
436
+ void testSelectionPriorityOrder () {
412
437
VoltageLevel vlgen7 = network .getVoltageLevel ("VLGEN7" );
413
- // Open all switches connecting busbars
438
+ // Open all coupling disconnectors
414
439
vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS1" ).setOpen (true );
415
440
vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS2" ).setOpen (true );
416
441
vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS3" ).setOpen (true );
417
442
vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS4" ).setOpen (true );
418
- vlgen7 .getNodeBreakerView ().getSwitch ("FORK_SW1" ).setOpen (true );
419
- vlgen7 .getNodeBreakerView ().getSwitch ("FORK_SW2" ).setOpen (true );
443
+ // But keep fork connections
420
444
Line line7 = network .getLine ("LINE7_FORK" );
421
- Terminal terminal = line7 .getTerminal2 ();
422
- BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( terminal );
445
+ BusbarSectionFinderTraverser . BusbarSectionResult result = BusbarSectionFinderTraverser . findBestBusbar ( line7 .getTerminal2 () );
446
+ // Must find a busbar with open switch priority 2
423
447
assertNotNull (result );
424
- assertEquals ("BUS1_NGEN7" , result .busbarSectionId ());
425
- assertEquals (4 , result .depth ());
426
- assertEquals (3 , result .switchesBeforeLast ());
427
448
assertNotNull (result .lastSwitch ());
428
- assertEquals ("SECT_BUS1" , result .lastSwitch ().id ());
429
- assertEquals (SwitchKind .DISCONNECTOR , result .lastSwitch ().kind ());
430
449
assertTrue (result .lastSwitch ().isOpen ());
431
- assertEquals (0 , result .lastSwitch ().node1 ());
432
- assertEquals (6 , result .lastSwitch ().node2 ());
433
450
}
434
451
435
452
@ Test
436
- void testPrefersShortestClosedPath () {
453
+ void testReturnsResultEvenWithNoClosedPaths () {
454
+ VoltageLevel vlgen7 = network .getVoltageLevel ("VLGEN7" );
455
+ // Open all coupling switches but keep fork switches
456
+ vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS1" ).setOpen (true );
457
+ vlgen7 .getNodeBreakerView ().getSwitch ("SECT_BUS2" ).setOpen (true );
437
458
Line line7 = network .getLine ("LINE7_FORK" );
438
- Terminal terminal = line7 .getTerminal2 ();
439
- BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (terminal );
440
- // BUS2 should be preferred (3 switches) over potential longer paths
459
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
460
+ // Must return a result (busbar accessible via open switch)
441
461
assertNotNull (result );
442
- assertEquals ("BUS2_NGEN7" , result .busbarSectionId ());
443
- assertEquals (4 , result .depth ());
462
+ assertTrue (result .depth () > 0 );
444
463
}
445
464
446
465
@ Test
447
- void testForkTopologySharesBusbar () {
466
+ void testForkLinesShareSameBusbar () {
448
467
Line line7 = network .getLine ("LINE7_FORK" );
449
468
Line line8 = network .getLine ("LINE8_FORK" );
450
469
String busbar7 = BusbarSectionFinderTraverser .findBusbarSectionId (line7 .getTerminal2 ());
451
470
String busbar8 = BusbarSectionFinderTraverser .findBusbarSectionId (line8 .getTerminal1 ());
471
+ // Both fork lines must find the same busbar
472
+ assertNotNull (busbar7 );
452
473
assertEquals (busbar7 , busbar8 );
453
474
assertEquals ("BUS2_NGEN7" , busbar7 );
454
475
}
@@ -472,4 +493,13 @@ void testHandlesMixedSwitchTypes() {
472
493
// Path contains both breakers and disconnectors
473
494
assertTrue (result .depth () > 0 );
474
495
}
496
+
497
+ @ Test
498
+ void testSwitchesBeforeLastCountAccuracy () {
499
+ Line line7 = network .getLine ("LINE7_FORK" );
500
+ BusbarSectionFinderTraverser .BusbarSectionResult result = BusbarSectionFinderTraverser .findBestBusbar (line7 .getTerminal2 ());
501
+ assertNotNull (result );
502
+ // With depth=4, we must have 3 switches before the last one
503
+ assertEquals (result .depth () - 1 , result .switchesBeforeLast ());
504
+ }
475
505
}
0 commit comments