From f6b6ebb1d7f0d253cbc14504f5c7f3e90ac7602c Mon Sep 17 00:00:00 2001 From: Jon Harper Date: Tue, 12 Sep 2023 15:13:13 +0200 Subject: [PATCH 1/5] Restore missing liquibase changeset (#326) fix bad merge in 779be32b5b --- src/main/resources/db/changelog/db.changelog-master.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From af443ab1bc8c9668cb782b156f3430134d295aec Mon Sep 17 00:00:00 2001 From: Jon Harper Date: Thu, 14 Sep 2023 09:58:42 +0200 Subject: [PATCH 2/5] remove unused liquibase changeset (#327) - the drop/add foreign key constraints are a bug we think from the shared constraint name between 2 tables - the horiz_poz and vert_pos notnull constraints are no longer relevant anywau (table removed in changelog_20230331T000231Z.xml (60dbfb32d58685be)) --- .../changesets/changelog_20230131T134433Z.xml | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/main/resources/db/changelog/changesets/changelog_20230131T134433Z.xml 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 @@ - - - - - - - - - - - - - - - - - - - - - From 290fdbaced6f9d755c01e815567787e7c21e846a Mon Sep 17 00:00:00 2001 From: FranckLecuyer <47824306+FranckLecuyer@users.noreply.github.com> Date: Thu, 14 Sep 2023 11:26:52 +0200 Subject: [PATCH 3/5] Fix possible null pointer exception on bus when computing hvdc balance (#329) * Fix possible null pointer exception on bus when computing hvdc balance Signed-off-by: Franck LECUYER --- .../server/modifications/GenerationDispatch.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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..ffa783887 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 -> { From 755fc4bef5d348bfae1a76d5af0891007b185737 Mon Sep 17 00:00:00 2001 From: dbraquart <107846716+dbraquart@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:23:16 +0200 Subject: [PATCH 4/5] avoid scalable error "maxValue should be bigger than minValue" in generator dispatch (#330) The error test case provided by the PO is now ok with this PR when we realize a generator dispatch Signed-off-by: David BRAQUART --- .../modifications/GenerationDispatch.java | 2 +- .../modifications/GenerationDispatchTest.java | 127 ++++++-- .../modification/server/utils/TestUtils.java | 18 +- ...stations_abattementIndispo_modifPmin.xiidm | 288 ++++++++++++++++++ 4 files changed, 405 insertions(+), 30 deletions(-) create mode 100644 src/test/resources/fourSubstations_abattementIndispo_modifPmin.xiidm 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 ffa783887..5146a609a 100644 --- a/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java +++ b/src/main/java/org/gridsuite/modification/server/modifications/GenerationDispatch.java @@ -376,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/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/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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 68f6a214e951209dccebb78a9bde61093acdf291 Mon Sep 17 00:00:00 2001 From: souissimai <133104748+souissimai@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:39:51 +0200 Subject: [PATCH 5/5] Fix logs for scaling modification (#328) *Fix logs for scaling modification --------- Signed-off-by: Maissa SOUISSI --- .../modification/server/modifications/AbstractScaling.java | 7 +++---- .../server/modifications/GeneratorScalingTest.java | 6 ++---- .../modification/server/modifications/LoadScalingTest.java | 6 ++---- 3 files changed, 7 insertions(+), 12 deletions(-) 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/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); }