diff --git a/src/main/java/org/gridsuite/modification/server/modifications/AbstractScaling.java b/src/main/java/org/gridsuite/modification/server/modifications/AbstractScaling.java index 57565cb70..59aeb0895 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/AbstractScaling.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/AbstractScaling.java @@ -70,17 +70,16 @@ public void apply(Network network, Reporter subReporter) { .allMatch(filterEquipments -> filterEquipments.getIdentifiableAttributes().isEmpty()); if (noValidEquipmentId) { - String errorMsg = "There is no valid equipment ID among the provided filter(s)"; + String errorMsg = scalingInfos.getErrorType() + ": There is no valid equipment ID among the provided filter(s)"; createReport(subReporter, "invalidFilters", errorMsg, TypedValue.ERROR_SEVERITY); - throw new NetworkModificationException(scalingInfos.getErrorType(), errorMsg); + return; } // create report for each wrong filter filterWithWrongEquipmentsIds.values().forEach(f -> { var equipmentIds = String.join(", ", f.getNotFoundEquipments()); - createReport(subReporter, - "filterEquipmentsNotFound", + "filterEquipmentsNotFound_" + f.getFilterName(), String.format("Cannot find the following equipments %s in filter %s", equipmentIds, filters.get(f.getFilterId())), TypedValue.WARN_SEVERITY); }); diff --git a/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java b/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java index 50de45336..5146a609a 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java @@ -100,8 +100,9 @@ private static double computeTotalAmountFixedSupply(Network network, Component c return totalAmountFixedSupply; } - private static Component getSynchronousComponentFrom(HvdcConverterStation station) { - return station.getTerminal().getBusView().getBus().getSynchronousComponent(); + private static boolean inDifferentSynchronousComponent(HvdcConverterStation station, int componentNum) { + Bus bus = station.getTerminal().getBusView().getBus(); + return bus != null && bus.getSynchronousComponent().getNum() != componentNum; } private static double computeHvdcBalance(Component component) { @@ -115,8 +116,8 @@ private static double computeHvdcBalance(Component component) { HvdcConverterStation station1 = hvdcLine.getConverterStation1(); HvdcConverterStation station2 = hvdcLine.getConverterStation2(); - boolean station2NotInComponent = station1.getId().equals(station.getId()) && getSynchronousComponentFrom(station2).getNum() != component.getNum(); - boolean station1NotInComponent = station2.getId().equals(station.getId()) && getSynchronousComponentFrom(station1).getNum() != component.getNum(); + boolean station2NotInComponent = station1.getId().equals(station.getId()) && inDifferentSynchronousComponent(station2, component.getNum()); + boolean station1NotInComponent = station2.getId().equals(station.getId()) && inDifferentSynchronousComponent(station1, component.getNum()); return station1NotInComponent || station2NotInComponent; }) .mapToDouble(station -> { @@ -375,7 +376,7 @@ private double reduceGeneratorMaxPValue(Generator generator, } } double genFrequencyReserve = computeGenFrequencyReserve(generator, generatorsFrequencyReserve); - return res * (1. - genFrequencyReserve / 100.); + return Math.max(generator.getMinP(), res * (1. - genFrequencyReserve / 100.)); } @Override diff --git a/src/main/resources/db/changelog/changesets/changelog_20230131T134433Z.xml b/src/main/resources/db/changelog/changesets/changelog_20230131T134433Z.xml deleted file mode 100644 index b3b9a1a31..000000000 --- a/src/main/resources/db/changelog/changesets/changelog_20230131T134433Z.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 9c3d4a87b..6a453045c 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -166,7 +166,7 @@ databaseChangeLog: file: changesets/changelog_20230702T105416Z.xml relativeToChangelogFile: true - include: - file: changesets/changelog_20230629T150259Z.xml + file: changesets/changelog_20230728T141452Z.xml relativeToChangelogFile: true - include: file: changesets/changelog_20230629T150259Z.xml diff --git a/src/test/java/org/gridsuite/modification/server/modifications/GenerationDispatchTest.java b/src/test/java/org/gridsuite/modification/server/modifications/GenerationDispatchTest.java index ec5a0cdfc..9f2c3d776 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/GenerationDispatchTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/GenerationDispatchTest.java @@ -7,6 +7,7 @@ package org.gridsuite.modification.server.modifications; +import com.fasterxml.jackson.core.type.TypeReference; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.matching.StringValuePattern; import com.powsybl.iidm.network.IdentifiableType; @@ -20,15 +21,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage; +import static org.gridsuite.modification.server.utils.TestUtils.assertLogNthMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -309,45 +314,58 @@ public void testGenerationDispatchGeneratorsWithFixedSupply() throws Exception { wireMockUtils.verifyGetRequest(stubIdForFixedSupply, PATH, handleQueryParams(getNetworkUuid(), filtersForFixedSupply.stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); } + private List getGeneratorsFiltersInfosWithFilters123() { + return List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_1).name("filter1").build(), + GeneratorsFilterInfos.builder().id(FILTER_ID_2).name("filter2").build(), + GeneratorsFilterInfos.builder().id(FILTER_ID_3).name("filter3").build()); + } + + private List getGeneratorsFrequencyReserveInfosWithFilters456() { + return List.of(GeneratorsFrequencyReserveInfos.builder().frequencyReserve(3.) + .generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_4).name("filter4").build(), + GeneratorsFilterInfos.builder().id(FILTER_ID_5).name("filter5").build())).build(), + GeneratorsFrequencyReserveInfos.builder().frequencyReserve(5.) + .generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_6).name("filter6").build())).build()); + } + + private List getGeneratorsWithoutOutageFilters123() { + return List.of(getFilterEquipments(FILTER_ID_1, "filter1", List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GROUP1_ID)), List.of()), + getFilterEquipments(FILTER_ID_2, "filter2", List.of(getIdentifiableAttributes(ABC_ID), getIdentifiableAttributes(GH3_ID)), List.of()), + getFilterEquipments(FILTER_ID_3, "filter3", List.of(getIdentifiableAttributes(GEN1_NOT_FOUND_ID), getIdentifiableAttributes(GEN2_NOT_FOUND_ID)), List.of(GEN1_NOT_FOUND_ID, GEN2_NOT_FOUND_ID))); + } + + private List getGeneratorsFrequencyReserveFilters45() { + return List.of(getFilterEquipments(FILTER_ID_4, "filter4", List.of(getIdentifiableAttributes(GTH1_ID)), List.of()), + getFilterEquipments(FILTER_ID_5, "filter5", List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GH3_ID)), List.of())); + } + + private List getGeneratorsFrequencyReserveFilter6() { + return List.of(getFilterEquipments(FILTER_ID_6, "filter6", List.of(getIdentifiableAttributes(TEST1_ID)), List.of())); + } + @Test public void testGenerationDispatchWithFrequencyReserve() throws Exception { ModificationInfos modification = buildModification(); ((GenerationDispatchInfos) modification).setDefaultOutageRate(15.); - ((GenerationDispatchInfos) modification).setGeneratorsWithoutOutage( - List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_1).name("filter1").build(), - GeneratorsFilterInfos.builder().id(FILTER_ID_2).name("filter2").build(), - GeneratorsFilterInfos.builder().id(FILTER_ID_3).name("filter3").build())); - ((GenerationDispatchInfos) modification).setGeneratorsFrequencyReserve( - List.of(GeneratorsFrequencyReserveInfos.builder().frequencyReserve(3.) - .generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_4).name("filter4").build(), - GeneratorsFilterInfos.builder().id(FILTER_ID_5).name("filter5").build())).build(), - GeneratorsFrequencyReserveInfos.builder().frequencyReserve(5.) - .generatorsFilters(List.of(GeneratorsFilterInfos.builder().id(FILTER_ID_6).name("filter6").build())).build())); + ((GenerationDispatchInfos) modification).setGeneratorsWithoutOutage(getGeneratorsFiltersInfosWithFilters123()); + ((GenerationDispatchInfos) modification).setGeneratorsFrequencyReserve(getGeneratorsFrequencyReserveInfosWithFilters456()); // network with 2 synchronous components, 2 hvdc lines between them, forcedOutageRate and plannedOutageRate defined for the generators setNetwork(Network.read("testGenerationDispatchReduceMaxP.xiidm", getClass().getResourceAsStream("/testGenerationDispatchReduceMaxP.xiidm"))); getNetwork().getGenerator("GH1").setMinP(20.); // to test scaling parameter allowsGeneratorOutOfActivePowerLimits - List filtersForPmaxReduction = List.of(getFilterEquipments(FILTER_ID_1, "filter1", List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GROUP1_ID)), List.of()), - getFilterEquipments(FILTER_ID_2, "filter2", List.of(getIdentifiableAttributes(ABC_ID), getIdentifiableAttributes(GH3_ID)), List.of()), - getFilterEquipments(FILTER_ID_3, "filter3", List.of(getIdentifiableAttributes(GEN1_NOT_FOUND_ID), getIdentifiableAttributes(GEN2_NOT_FOUND_ID)), List.of(GEN1_NOT_FOUND_ID, GEN2_NOT_FOUND_ID))); - UUID stubIdForPmaxReduction = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_1 + "," + FILTER_ID_2 + "," + FILTER_ID_3) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(filtersForPmaxReduction)) + .withBody(mapper.writeValueAsString(getGeneratorsWithoutOutageFilters123())) .withHeader("Content-Type", "application/json"))).getId(); - List filtersForFrequencyReserve1 = List.of(getFilterEquipments(FILTER_ID_4, "filter4", List.of(getIdentifiableAttributes(GTH1_ID)), List.of()), - getFilterEquipments(FILTER_ID_5, "filter5", List.of(getIdentifiableAttributes(GTH2_ID), getIdentifiableAttributes(GH3_ID)), List.of())); - List filtersForFrequencyReserve2 = List.of(getFilterEquipments(FILTER_ID_6, "filter6", List.of(getIdentifiableAttributes(TEST1_ID)), List.of())); - UUID stubIdForFrequencyReserve1 = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_4 + "," + FILTER_ID_5) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(filtersForFrequencyReserve1)) + .withBody(mapper.writeValueAsString(getGeneratorsFrequencyReserveFilters45())) .withHeader("Content-Type", "application/json"))).getId(); UUID stubIdForFrequencyReserve2 = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_6) .willReturn(WireMock.ok() - .withBody(mapper.writeValueAsString(filtersForFrequencyReserve2)) + .withBody(mapper.writeValueAsString(getGeneratorsFrequencyReserveFilter6())) .withHeader("Content-Type", "application/json"))).getId(); String modificationJson = mapper.writeValueAsString(modification); @@ -382,9 +400,9 @@ public void testGenerationDispatchWithFrequencyReserve() throws Exception { assertLogMessage("The total amount of supply to be dispatched is : 330.0 MW", "TotalAmountSupplyToBeDispatched" + secondSynchronousComponentNum, reportService); assertLogMessage("The supply-demand balance could be met", "SupplyDemandBalanceCouldBeMet" + secondSynchronousComponentNum, reportService); - wireMockUtils.verifyGetRequest(stubIdForPmaxReduction, PATH, handleQueryParams(getNetworkUuid(), filtersForPmaxReduction.stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); - wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve1, PATH, handleQueryParams(getNetworkUuid(), filtersForFrequencyReserve1.stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); - wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve2, PATH, handleQueryParams(getNetworkUuid(), filtersForFrequencyReserve2.stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + wireMockUtils.verifyGetRequest(stubIdForPmaxReduction, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsWithoutOutageFilters123().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve1, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsFrequencyReserveFilters45().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve2, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsFrequencyReserveFilter6().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); } @Test @@ -478,6 +496,67 @@ public void testGenerationDispatchErrorCheck() { assertThrows("GENERATION_DISPATCH_ERROR : The default outage rate must be between 0 and 100", NetworkModificationException.class, () -> generationDispatch2.check(getNetwork())); } + @Test + public void testGenerationDispatchWithMaxValueLessThanMinP() throws Exception { + ModificationInfos modification = GenerationDispatchInfos.builder() + .lossCoefficient(20.) + .defaultOutageRate(15.) + .generatorsWithoutOutage(getGeneratorsFiltersInfosWithFilters123()) + .generatorsWithFixedSupply(List.of()) + .generatorsFrequencyReserve(getGeneratorsFrequencyReserveInfosWithFilters456()) + .substationsGeneratorsOrdering(List.of()) + .build(); + + // dedicated case + setNetwork(Network.read("fourSubstations_abattementIndispo_modifPmin.xiidm", getClass().getResourceAsStream("/fourSubstations_abattementIndispo_modifPmin.xiidm"))); + + // Stub filters queries + UUID stubIdForPmaxReduction = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_1 + "," + FILTER_ID_2 + "," + FILTER_ID_3) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(getGeneratorsWithoutOutageFilters123())) + .withHeader("Content-Type", "application/json"))).getId(); + UUID stubIdForFrequencyReserve1 = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_4 + "," + FILTER_ID_5) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(getGeneratorsFrequencyReserveFilters45())) + .withHeader("Content-Type", "application/json"))).getId(); + UUID stubIdForFrequencyReserve2 = wireMockServer.stubFor(WireMock.get(getPath(getNetworkUuid(), false) + FILTER_ID_6) + .willReturn(WireMock.ok() + .withBody(mapper.writeValueAsString(getGeneratorsFrequencyReserveFilter6())) + .withHeader("Content-Type", "application/json"))).getId(); + + String modificationJson = mapper.writeValueAsString(modification); + MvcResult mvcResult = mockMvc.perform(post(getNetworkModificationUri()).content(modificationJson).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + Optional modifResult = mapper.readValue(mvcResult.getResponse().getContentAsString(), new TypeReference<>() { }); + assertTrue(modifResult.isPresent()); + assertEquals(NetworkModificationResult.ApplicationStatus.WITH_WARNINGS, modifResult.get().getApplicationStatus()); + + // check logs + int firstSynchronousComponentNum = getNetwork().getGenerator(GTH1_ID).getTerminal().getBusView().getBus().getSynchronousComponent().getNum(); // GTH1 is in first synchronous component + assertLogMessage("The total demand is : 528.0 MW", "TotalDemand" + firstSynchronousComponentNum, reportService); + assertLogMessage("The total amount of fixed supply is : 0.0 MW", "TotalAmountFixedSupply" + firstSynchronousComponentNum, reportService); + assertLogMessage("The HVDC balance is : 90.0 MW", "TotalOutwardHvdcFlow" + firstSynchronousComponentNum, reportService); + assertLogMessage("The total amount of supply to be dispatched is : 438.0 MW", "TotalAmountSupplyToBeDispatched" + firstSynchronousComponentNum, reportService); + assertLogNthMessage("Generator TEST1 targetP : 0.0 MW --> 40.375 MW", "GeneratorSetTargetP" + firstSynchronousComponentNum, reportService, 1); + assertLogNthMessage("Generator GTH1 targetP : 0.0 MW --> 80.0 MW", "GeneratorSetTargetP" + firstSynchronousComponentNum, reportService, 2); + assertLogNthMessage("Generator GTH2 targetP : 0.0 MW --> 146.0 MW", "GeneratorSetTargetP" + firstSynchronousComponentNum, reportService, 3); + assertLogMessage("The supply-demand balance could not be met : the remaining power imbalance is 171.625 MW", "SupplyDemandBalanceCouldNotBeMet" + firstSynchronousComponentNum, reportService); + int secondSynchronousComponentNum = getNetwork().getGenerator(GH1_ID).getTerminal().getBusView().getBus().getSynchronousComponent().getNum(); // GH1 is in second synchronous component + assertLogMessage("The total demand is : 240.0 MW", "TotalDemand" + secondSynchronousComponentNum, reportService); + assertLogMessage("The total amount of fixed supply is : 0.0 MW", "TotalAmountFixedSupply" + secondSynchronousComponentNum, reportService); + assertLogMessage("The HVDC balance is : -90.0 MW", "TotalOutwardHvdcFlow" + secondSynchronousComponentNum, reportService); + assertLogMessage("The total amount of supply to be dispatched is : 330.0 MW", "TotalAmountSupplyToBeDispatched" + secondSynchronousComponentNum, reportService); + assertLogNthMessage("Generator GH1 targetP : 0.0 MW --> 80.0 MW", "GeneratorSetTargetP" + secondSynchronousComponentNum, reportService, 1); + assertLogNthMessage("Generator GH2 targetP : 0.0 MW --> 60.0 MW", "GeneratorSetTargetP" + secondSynchronousComponentNum, reportService, 2); + assertLogNthMessage("Generator GH3 targetP : 0.0 MW --> 126.1 MW", "GeneratorSetTargetP" + secondSynchronousComponentNum, reportService, 3); + assertLogNthMessage("Generator ABC targetP : 0.0 MW --> 63.900000000000006 MW", "GeneratorSetTargetP" + secondSynchronousComponentNum, reportService, 4); + assertLogMessage("The supply-demand balance could be met", "SupplyDemandBalanceCouldBeMet" + secondSynchronousComponentNum, reportService); + + wireMockUtils.verifyGetRequest(stubIdForPmaxReduction, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsWithoutOutageFilters123().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve1, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsFrequencyReserveFilters45().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + wireMockUtils.verifyGetRequest(stubIdForFrequencyReserve2, PATH, handleQueryParams(getNetworkUuid(), getGeneratorsFrequencyReserveFilter6().stream().map(FilterEquipments::getFilterId).collect(Collectors.toList())), false); + } + @Override protected Network createNetwork(UUID networkUuid) { return Network.read("testGenerationDispatch.xiidm", getClass().getResourceAsStream("/testGenerationDispatch.xiidm")); diff --git a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorScalingTest.java b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorScalingTest.java index 59b39c72f..16c35ea46 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/GeneratorScalingTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/GeneratorScalingTest.java @@ -12,7 +12,6 @@ import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.extensions.ConnectablePosition; -import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.VariationMode; import org.gridsuite.modification.server.VariationType; import org.gridsuite.modification.server.dto.*; @@ -30,7 +29,6 @@ import java.util.UUID; import java.util.stream.Collectors; -import static org.gridsuite.modification.server.NetworkModificationException.Type.GENERATOR_SCALING_ERROR; import static org.gridsuite.modification.server.utils.NetworkUtil.createGenerator; import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage; import static org.junit.Assert.assertEquals; @@ -206,8 +204,8 @@ public void testFilterWithWrongIds() throws Exception { mockMvc.perform(post(getNetworkModificationUri()).content(mapper.writeValueAsString(generatorScalingInfo)).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); - assertLogMessage(new NetworkModificationException(GENERATOR_SCALING_ERROR, "There is no valid equipment ID among the provided filter(s)").getMessage(), - generatorScalingInfo.getErrorType().name(), reportService); + assertLogMessage(generatorScalingInfo.getErrorType().name() + ": There is no valid equipment ID among the provided filter(s)", + "invalidFilters", reportService); wireMockUtils.verifyGetRequest(subWrongId, PATH, handleQueryParams(getNetworkUuid(), FILTER_WRONG_ID_1), false); } diff --git a/src/test/java/org/gridsuite/modification/server/modifications/LoadScalingTest.java b/src/test/java/org/gridsuite/modification/server/modifications/LoadScalingTest.java index 226697db3..3c5ae32ca 100644 --- a/src/test/java/org/gridsuite/modification/server/modifications/LoadScalingTest.java +++ b/src/test/java/org/gridsuite/modification/server/modifications/LoadScalingTest.java @@ -12,7 +12,6 @@ import com.powsybl.iidm.network.IdentifiableType; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.extensions.ConnectablePosition; -import org.gridsuite.modification.server.NetworkModificationException; import org.gridsuite.modification.server.ReactiveVariationMode; import org.gridsuite.modification.server.VariationMode; import org.gridsuite.modification.server.VariationType; @@ -32,7 +31,6 @@ import java.util.UUID; import java.util.stream.Collectors; -import static org.gridsuite.modification.server.NetworkModificationException.Type.LOAD_SCALING_ERROR; import static org.gridsuite.modification.server.utils.NetworkUtil.createLoad; import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage; import static org.junit.Assert.assertEquals; @@ -225,8 +223,8 @@ public void testFilterWithWrongIds() throws Exception { .content(mapper.writeValueAsString(loadScalingInfo)) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()); - assertLogMessage(new NetworkModificationException(LOAD_SCALING_ERROR, "There is no valid equipment ID among the provided filter(s)").getMessage(), - loadScalingInfo.getErrorType().name(), reportService); + assertLogMessage(loadScalingInfo.getErrorType().name() + ": There is no valid equipment ID among the provided filter(s)", + "invalidFilters", reportService); wireMockUtils.verifyGetRequest(stubWithWrongId, PATH, handleQueryParams(getNetworkUuid(), FILTER_WRONG_ID_1), false); } diff --git a/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java b/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java index 7035c84f3..5b1d2a7b4 100644 --- a/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java +++ b/src/test/java/org/gridsuite/modification/server/utils/TestUtils.java @@ -133,29 +133,37 @@ public static String resourceToString(String resource) throws IOException { return StringUtils.replaceWhitespaceCharacters(content, ""); } - public static void assertLogMessage(String expectedMessage, String reportKey, ReportService reportService) { + public static void assertLogNthMessage(String expectedMessage, String reportKey, ReportService reportService, int rank) { ArgumentCaptor reporterCaptor = ArgumentCaptor.forClass(ReporterModel.class); verify(reportService, atLeast(1)).sendReport(any(UUID.class), reporterCaptor.capture()); assertNotNull(reporterCaptor.getValue()); - Optional message = getMessageFromReporter(reportKey, reporterCaptor.getValue()); + Optional message = getMessageFromReporter(reportKey, reporterCaptor.getValue(), rank); assertTrue(message.isPresent()); assertEquals(expectedMessage, message.get()); } - private static Optional getMessageFromReporter(String reportKey, ReporterModel reporterModel) { + public static void assertLogMessage(String expectedMessage, String reportKey, ReportService reportService) { + assertLogNthMessage(expectedMessage, reportKey, reportService, 1); + } + + private static Optional getMessageFromReporter(String reportKey, ReporterModel reporterModel, int rank) { Optional message = Optional.empty(); Iterator reportsIterator = reporterModel.getReports().iterator(); + int nbTimes = 0; while (message.isEmpty() && reportsIterator.hasNext()) { Report report = reportsIterator.next(); if (report.getReportKey().equals(reportKey)) { - message = Optional.of(formatReportMessage(report, reporterModel)); + nbTimes++; + if (nbTimes == rank) { + message = Optional.of(formatReportMessage(report, reporterModel)); + } } } Iterator reportersIterator = reporterModel.getSubReporters().iterator(); while (message.isEmpty() && reportersIterator.hasNext()) { - message = getMessageFromReporter(reportKey, reportersIterator.next()); + message = getMessageFromReporter(reportKey, reportersIterator.next(), rank); } return message; diff --git a/src/test/resources/fourSubstations_abattementIndispo_modifPmin.xiidm b/src/test/resources/fourSubstations_abattementIndispo_modifPmin.xiidm new file mode 100644 index 000000000..3e873b576 --- /dev/null +++ b/src/test/resources/fourSubstations_abattementIndispo_modifPmin.xiidm @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +