Skip to content

Commit 3cc8f71

Browse files
authored
Properly handle out of voltage bus error (#73)
Signed-off-by: David SARTORI <[email protected]>
1 parent 9c1884f commit 3cc8f71

File tree

3 files changed

+145
-28
lines changed

3 files changed

+145
-28
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright (c) 2024, RTE (http://www.rte-france.com)
3+
* This Source Code Form is subject to the terms of the Mozilla Public
4+
* License, v. 2.0. If a copy of the MPL was not distributed with this
5+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
*/
7+
package org.gridsuite.shortcircuit.server;
8+
9+
import lombok.Getter;
10+
11+
import java.util.Objects;
12+
13+
/**
14+
* @author David SARTORI <david.sartori_externe at rte-france.com>
15+
*/
16+
@Getter
17+
public class ShortCircuitException extends RuntimeException {
18+
19+
public enum Type {
20+
BUS_OUT_OF_VOLTAGE
21+
}
22+
23+
private final Type type;
24+
25+
public ShortCircuitException(Type type) {
26+
super(Objects.requireNonNull(type.name()));
27+
this.type = type;
28+
}
29+
30+
public ShortCircuitException(Type type, String message) {
31+
super(message);
32+
this.type = type;
33+
}
34+
}

src/main/java/org/gridsuite/shortcircuit/server/service/ShortCircuitWorkerService.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.commons.lang3.StringUtils;
2020
import org.gridsuite.shortcircuit.server.dto.ShortCircuitAnalysisStatus;
2121
import org.gridsuite.shortcircuit.server.dto.ShortCircuitLimits;
22+
import org.gridsuite.shortcircuit.server.ShortCircuitException;
2223
import org.gridsuite.shortcircuit.server.reports.AbstractReportMapper;
2324
import org.gridsuite.shortcircuit.server.repositories.ShortCircuitAnalysisResultRepository;
2425
import org.slf4j.Logger;
@@ -38,6 +39,7 @@
3839
import java.util.function.Consumer;
3940
import java.util.stream.Collectors;
4041

42+
import static org.gridsuite.shortcircuit.server.ShortCircuitException.Type.BUS_OUT_OF_VOLTAGE;
4143
import static org.gridsuite.shortcircuit.server.service.NotificationService.CANCEL_MESSAGE;
4244
import static org.gridsuite.shortcircuit.server.service.NotificationService.FAIL_MESSAGE;
4345

@@ -148,14 +150,17 @@ private List<Fault> getBusFaultFromBusId(Network network, ShortCircuitRunContext
148150
Identifiable<?> identifiable = network.getIdentifiable(busId);
149151
Map<String, ShortCircuitLimits> shortCircuitLimits = new HashMap<>();
150152

151-
if (identifiable instanceof BusbarSection) {
152-
String busIdFromBusView = ((BusbarSection) identifiable).getTerminal().getBusView().getBus().getId();
153+
if (identifiable instanceof BusbarSection busbarSection) {
154+
Bus bus = busbarSection.getTerminal().getBusView().getBus();
155+
if (bus == null) {
156+
throw new ShortCircuitException(BUS_OUT_OF_VOLTAGE, "Selected bus is out of voltage");
157+
}
153158
IdentifiableShortCircuit<VoltageLevel> shortCircuitExtension = ((BusbarSection) identifiable).getTerminal().getBusView().getBus().getVoltageLevel().getExtension(IdentifiableShortCircuit.class);
154159
if (shortCircuitExtension != null) {
155-
shortCircuitLimits.put(busIdFromBusView, new ShortCircuitLimits(shortCircuitExtension.getIpMin(), shortCircuitExtension.getIpMax()));
160+
shortCircuitLimits.put(bus.getId(), new ShortCircuitLimits(shortCircuitExtension.getIpMin(), shortCircuitExtension.getIpMax()));
156161
}
157162
context.setShortCircuitLimits(shortCircuitLimits);
158-
return List.of(new BusFault(busIdFromBusView, busIdFromBusView));
163+
return List.of(new BusFault(bus.getId(), bus.getId()));
159164
}
160165

161166
if (identifiable instanceof Bus) {

src/test/java/org/gridsuite/shortcircuit/server/service/ShortCircuitServiceTest.java

Lines changed: 102 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,19 @@
1010
import com.powsybl.commons.reporter.Reporter;
1111
import com.powsybl.commons.reporter.ReporterModel;
1212
import com.powsybl.computation.ComputationManager;
13+
import com.powsybl.iidm.network.BusbarSection;
1314
import com.powsybl.iidm.network.Network;
15+
import com.powsybl.iidm.network.Terminal;
16+
import com.powsybl.iidm.network.Terminal.BusView;
1417
import com.powsybl.iidm.network.VariantManager;
1518
import com.powsybl.network.store.client.NetworkStoreService;
1619
import com.powsybl.network.store.client.PreloadingStrategy;
17-
import com.powsybl.shortcircuit.*;
20+
import com.powsybl.shortcircuit.Fault;
21+
import com.powsybl.shortcircuit.FaultParameters;
22+
import com.powsybl.shortcircuit.ShortCircuitAnalysis;
23+
import com.powsybl.shortcircuit.ShortCircuitAnalysisProvider;
24+
import com.powsybl.shortcircuit.ShortCircuitAnalysisResult;
25+
import com.powsybl.shortcircuit.ShortCircuitParameters;
1826
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
1927
import io.micrometer.observation.ObservationRegistry;
2028
import lombok.AllArgsConstructor;
@@ -23,38 +31,85 @@
2331
import org.gridsuite.shortcircuit.server.TestUtils;
2432
import org.gridsuite.shortcircuit.server.reports.AbstractReportMapper;
2533
import org.gridsuite.shortcircuit.server.repositories.ShortCircuitAnalysisResultRepository;
34+
import org.junit.jupiter.api.BeforeEach;
2635
import org.junit.jupiter.api.Test;
2736
import org.junit.jupiter.api.extension.ExtendWith;
37+
import org.mockito.Mock;
2838
import org.mockito.MockedStatic;
2939
import org.mockito.Mockito;
3040
import org.mockito.junit.jupiter.MockitoExtension;
3141
import org.springframework.messaging.Message;
3242
import org.springframework.messaging.support.GenericMessage;
3343

44+
import java.util.Collections;
3445
import java.util.List;
3546
import java.util.UUID;
3647
import java.util.concurrent.CompletableFuture;
3748
import java.util.stream.Stream;
3849

39-
import static org.mockito.ArgumentMatchers.*;
50+
import static org.mockito.ArgumentMatchers.any;
51+
import static org.mockito.ArgumentMatchers.anyList;
52+
import static org.mockito.ArgumentMatchers.eq;
4053
import static org.mockito.Mockito.atLeastOnce;
54+
import static org.mockito.Mockito.doReturn;
55+
import static org.mockito.Mockito.mock;
56+
import static org.mockito.Mockito.mockStatic;
57+
import static org.mockito.Mockito.spy;
4158
import static org.mockito.Mockito.times;
59+
import static org.mockito.Mockito.verify;
60+
import static org.mockito.Mockito.when;
4261

4362
@ExtendWith({ MockitoExtension.class })
4463
@Slf4j
4564
class ShortCircuitServiceTest implements WithAssertions {
65+
66+
@Mock
67+
private NetworkStoreService networkStoreService;
68+
69+
@Mock
70+
private ReportService reportService;
71+
72+
@Mock
73+
private ShortCircuitExecutionService shortCircuitExecutionService;
74+
75+
@Mock
76+
private NotificationService notificationService;
77+
78+
@Mock
79+
private ShortCircuitAnalysisResultRepository resultRepository;
80+
81+
@Mock
82+
private ObjectMapper objectMapper;
83+
84+
@Mock
85+
private AbstractReportMapper reportMapper;
86+
87+
@Mock
88+
private Network network;
89+
90+
@Mock
91+
private VariantManager variantManager;
92+
93+
private ShortCircuitWorkerService workerService;
94+
95+
@BeforeEach
96+
void init() {
97+
workerService = new ShortCircuitWorkerService(
98+
networkStoreService,
99+
reportService,
100+
shortCircuitExecutionService,
101+
notificationService,
102+
resultRepository,
103+
objectMapper,
104+
Collections.singletonList(reportMapper),
105+
new ShortCircuitObserver(ObservationRegistry.create(), new SimpleMeterRegistry())
106+
);
107+
}
108+
46109
@Test
47110
void testLogsMappersIsCalled() throws Exception {
48-
final AbstractReportMapper reportMapperMocked = Mockito.mock(AbstractReportMapper.class);
49-
final NetworkStoreService networkStoreServiceMocked = Mockito.mock(NetworkStoreService.class);
50-
final ReportService reportServiceMocked = Mockito.mock(ReportService.class);
51-
final ShortCircuitExecutionService shortCircuitExecutionService = Mockito.mock(ShortCircuitExecutionService.class);
52-
final NotificationService notificationServiceMocked = Mockito.mock(NotificationService.class);
53-
final ShortCircuitAnalysisResultRepository resultRepositoryMocked = Mockito.mock(ShortCircuitAnalysisResultRepository.class);
54-
final ObjectMapper objectMapperMocked = Mockito.mock(ObjectMapper.class);
55-
56111
final ShortCircuitAnalysisResult analysisResult = new ShortCircuitAnalysisResult(List.of());
57-
final ShortCircuitAnalysisProvider providerMock = Mockito.spy(new ShortCircuitAnalysisProviderMock(analysisResult));
112+
final ShortCircuitAnalysisProvider providerMock = spy(new ShortCircuitAnalysisProviderMock(analysisResult));
58113
final Message<String> message = new GenericMessage<>("test");
59114
final UUID networkUuid = UUID.fromString("11111111-1111-1111-1111-111111111111");
60115
final UUID reportUuid = UUID.fromString("22222222-2222-2222-2222-222222222222");
@@ -63,29 +118,52 @@ void testLogsMappersIsCalled() throws Exception {
63118
final ShortCircuitRunContext runContext = new ShortCircuitRunContext(networkUuid, null, null,
64119
new ShortCircuitParameters(), reportUuid, reporterId, "AllBusesShortCircuitAnalysis", null, null);
65120
final ShortCircuitResultContext resultContext = new ShortCircuitResultContext(resultUuid, runContext);
66-
final Network networkMocked = Mockito.mock(Network.class);
67-
final VariantManager variantManagerMocked = Mockito.mock(VariantManager.class);
68121
final Network.BusView busViewMocked = Mockito.mock(Network.BusView.class);
69122
final Reporter reporter = new ReporterModel("test", "test");
70-
final ShortCircuitObserver shortCircuitObserver = new ShortCircuitObserver(ObservationRegistry.create(), new SimpleMeterRegistry());
71123

72124
try (final MockedStatic<ShortCircuitAnalysis> shortCircuitAnalysisMockedStatic = TestUtils.injectShortCircuitAnalysisProvider(providerMock);
73-
final MockedStatic<ShortCircuitResultContext> shortCircuitResultContextMockedStatic = Mockito.mockStatic(ShortCircuitResultContext.class)) {
125+
final MockedStatic<ShortCircuitResultContext> shortCircuitResultContextMockedStatic = mockStatic(ShortCircuitResultContext.class)) {
74126
shortCircuitAnalysisMockedStatic.when(() -> ShortCircuitAnalysis.runAsync(any(), anyList(), any(), any(), anyList(), any()))
75127
.thenAnswer(invocation -> CompletableFuture.completedFuture(analysisResult));
76128
shortCircuitAnalysisMockedStatic.when(() -> ShortCircuitAnalysis.runAsync(any(), anyList(), any(), any(), anyList(), any()))
77129
.thenAnswer(invocation -> CompletableFuture.completedFuture(analysisResult));
78-
shortCircuitResultContextMockedStatic.when(() -> ShortCircuitResultContext.fromMessage(message, objectMapperMocked)).thenReturn(resultContext);
79-
Mockito.when(networkStoreServiceMocked.getNetwork(eq(networkUuid), any(PreloadingStrategy.class))).thenReturn(networkMocked);
80-
Mockito.when(networkMocked.getVariantManager()).thenReturn(variantManagerMocked);
81-
Mockito.when(networkMocked.getBusView()).thenReturn(busViewMocked);
82-
Mockito.when(busViewMocked.getBusStream()).thenAnswer(invocation -> Stream.empty());
83-
Mockito.when(reportMapperMocked.processReporter(any(Reporter.class))).thenReturn(reporter);
84-
final ShortCircuitWorkerService workerService = new ShortCircuitWorkerService(networkStoreServiceMocked, reportServiceMocked, shortCircuitExecutionService, notificationServiceMocked, resultRepositoryMocked, objectMapperMocked, List.of(reportMapperMocked), shortCircuitObserver);
130+
shortCircuitResultContextMockedStatic.when(() -> ShortCircuitResultContext.fromMessage(message, objectMapper)).thenReturn(resultContext);
131+
when(networkStoreService.getNetwork(eq(networkUuid), any(PreloadingStrategy.class))).thenReturn(network);
132+
when(network.getVariantManager()).thenReturn(variantManager);
133+
when(network.getBusView()).thenReturn(busViewMocked);
134+
when(busViewMocked.getBusStream()).thenAnswer(invocation -> Stream.empty());
135+
when(reportMapper.processReporter(any(Reporter.class))).thenReturn(reporter);
85136
workerService.consumeRun().accept(message);
86137
shortCircuitAnalysisMockedStatic.verify(ShortCircuitAnalysis::find, atLeastOnce());
87-
Mockito.verify(reportMapperMocked, times(1)).processReporter(any(ReporterModel.class));
88-
Mockito.verify(reportServiceMocked, times(1)).sendReport(reportUuid, reporter);
138+
verify(reportMapper, times(1)).processReporter(any(ReporterModel.class));
139+
verify(reportService, times(1)).sendReport(reportUuid, reporter);
140+
}
141+
}
142+
143+
@Test
144+
void testGetBusFaultFromOutOfVoltageBus() throws Exception {
145+
var analysisProvider = spy(new ShortCircuitAnalysisProviderMock(new ShortCircuitAnalysisResult(Collections.emptyList())));
146+
var message = new GenericMessage<>("test");
147+
var runContext = mock(ShortCircuitRunContext.class);
148+
var resultContext = new ShortCircuitResultContext(UUID.randomUUID(), runContext);
149+
var busbarSection = mock(BusbarSection.class);
150+
var terminal = mock(Terminal.class);
151+
var busView = mock(BusView.class);
152+
var busId = "bus1";
153+
154+
when(runContext.getBusId()).thenReturn(busId);
155+
when(networkStoreService.getNetwork(any(), any())).thenReturn(network);
156+
doReturn(busbarSection).when(network).getIdentifiable(busId);
157+
when(network.getVariantManager()).thenReturn(variantManager);
158+
when(busbarSection.getTerminal()).thenReturn(terminal);
159+
when(terminal.getBusView()).thenReturn(busView);
160+
when(busView.getBus()).thenReturn(null);
161+
162+
try (var shortCircuitAnalysisMockedStatic = TestUtils.injectShortCircuitAnalysisProvider(analysisProvider);
163+
var shortCircuitResultContextMockedStatic = mockStatic(ShortCircuitResultContext.class)) {
164+
shortCircuitResultContextMockedStatic.when(() -> ShortCircuitResultContext.fromMessage(message, objectMapper)).thenReturn(resultContext);
165+
workerService.consumeRun().accept(message);
166+
verify(notificationService).publishFail(any(), any(), eq("Selected bus is out of voltage"), any(), eq(busId));
89167
}
90168
}
91169

0 commit comments

Comments
 (0)