CracImportExportTest.java
/*
* Copyright (c) 2020, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.openrao.data.crac.io.json;
import com.powsybl.action.*;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Crac;
import com.powsybl.openrao.data.crac.api.CracCreationContext;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.NetworkElement;
import com.powsybl.openrao.data.crac.api.RaUsageLimits;
import com.powsybl.openrao.data.crac.api.usagerule.OnConstraint;
import com.powsybl.openrao.data.crac.api.usagerule.OnContingencyState;
import com.powsybl.openrao.data.crac.api.usagerule.OnFlowConstraintInCountry;
import com.powsybl.openrao.data.crac.api.usagerule.OnInstant;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import com.powsybl.openrao.data.crac.api.usagerule.UsageRule;
import com.powsybl.openrao.data.crac.api.cnec.AngleCnec;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.cnec.VoltageCnec;
import com.powsybl.openrao.data.crac.api.networkaction.SwitchPair;
import com.powsybl.openrao.data.crac.api.parameters.CracCreationParameters;
import com.powsybl.openrao.data.crac.api.range.RangeType;
import com.powsybl.openrao.data.crac.api.range.StandardRange;
import com.powsybl.openrao.data.crac.api.range.TapRange;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.crac.api.threshold.BranchThreshold;
import com.powsybl.openrao.data.crac.impl.utils.ExhaustiveCracCreation;
import com.powsybl.openrao.data.crac.impl.utils.NetworkImportsUtil;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.io.IOException;
import java.io.InputStream;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.powsybl.openrao.data.crac.api.usagerule.UsageMethod.AVAILABLE;
import static com.powsybl.openrao.data.crac.api.usagerule.UsageMethod.FORCED;
import static com.powsybl.openrao.data.crac.io.json.RoundTripUtil.implicitJsonRoundTrip;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Joris Mancini {@literal <joris.mancini at rte-france.com>}
*/
class CracImportExportTest {
@Test
void testExists() {
assertTrue(new JsonImport().exists("crac-v2.5.json", getClass().getResourceAsStream("/retrocompatibility/v2/crac-v2.5.json")));
assertTrue(new JsonImport().exists("cracHeader.json", getClass().getResourceAsStream("/cracHeader.json")));
assertFalse(new JsonImport().exists("invalidCrac.json", getClass().getResourceAsStream("/invalidCrac.json")));
assertFalse(new JsonImport().exists("invalidCrac.txt", getClass().getResourceAsStream("/invalidCrac.txt")));
}
@Test
void testImportCracWithUnknownVersion() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> new JsonImport().exists("crac-v100.0.json", getClass().getResourceAsStream("/crac-v100.0.json")));
assertEquals("v100.0 is not a valid JSON CRAC version.", exception.getMessage());
}
@Test
void testNonNullOffsetDateTime() {
Network network = NetworkImportsUtil.createNetworkForJsonRetrocompatibilityTest();
CracCreationContext context = new JsonImport().importData(getClass().getResourceAsStream("/retrocompatibility/v2/crac-v2.5.json"), new CracCreationParameters(), network);
assertTrue(context.isCreationSuccessful());
assertNull(context.getTimeStamp());
assertEquals("test", context.getNetworkName());
}
@Test
void testPstMissingInNetwork() {
Network network = NetworkImportsUtil.createNetworkForJsonRetrocompatibilityTest();
CracCreationContext context = new JsonImport().importData(getClass().getResourceAsStream("/cracMissingPst.json"), new CracCreationParameters(), network);
assertFalse(context.isCreationSuccessful());
assertEquals(List.of("[ERROR] PST missing-pst does not exist in the current network"), context.getCreationReport().getReport());
}
@Test
void testImportFailure() {
CracCreationContext context = new JsonImport().importData(getClass().getResourceAsStream("/retrocompatibility/v2/crac-v2.5.json"), new CracCreationParameters(), Mockito.mock(Network.class));
assertNotNull(context);
assertFalse(context.isCreationSuccessful());
assertNull(context.getCrac());
assertEquals(List.of("[ERROR] In Contingency, network element with id ne1Id does not exist in network null, so it does not have type information and can not be converted to a contingency element."), context.getCreationReport().getReport());
}
@Test
void explicitJsonRoundTripTest() {
Crac crac = ExhaustiveCracCreation.create();
Crac importedCrac = RoundTripUtil.explicitJsonRoundTrip(crac, ExhaustiveCracCreation.createAssociatedNetwork());
checkContent(importedCrac);
}
@Test
void implicitJsonRoundTripTest() {
Crac crac = ExhaustiveCracCreation.create();
Crac importedCrac = implicitJsonRoundTrip(crac, ExhaustiveCracCreation.createAssociatedNetwork());
checkContent(importedCrac);
}
private void checkContent(Crac crac) {
Instant preventiveInstant = crac.getInstant("preventive");
Instant autoInstant = crac.getInstant("auto");
Instant curativeInstant = crac.getInstant("curative");
// check timestamp
assertTrue(crac.getTimestamp().isPresent());
assertEquals(OffsetDateTime.of(2025, 2, 3, 10, 12, 0, 0, ZoneOffset.UTC), crac.getTimestamp().get());
// check overall content
assertNotNull(crac);
assertEquals(5, crac.getStates().size());
assertEquals(2, crac.getContingencies().size());
assertEquals(7, crac.getFlowCnecs().size());
assertEquals(1, crac.getAngleCnecs().size());
assertEquals(1, crac.getVoltageCnecs().size());
assertEquals(9, crac.getRangeActions().size());
assertEquals(5, crac.getNetworkActions().size());
// --------------------------
// --- test Ra Usage Limits ---
// --------------------------
RaUsageLimits expectedUsageLimits = crac.getRaUsageLimits(curativeInstant);
assertEquals(4, expectedUsageLimits.getMaxRa());
assertEquals(2, expectedUsageLimits.getMaxTso());
assertEquals(Map.of("FR", 12), expectedUsageLimits.getMaxRaPerTso());
assertEquals(Map.of("FR", 7), expectedUsageLimits.getMaxPstPerTso());
assertEquals(Map.of("FR", 5, "BE", 6), expectedUsageLimits.getMaxTopoPerTso());
assertEquals(Map.of("FR", 21), expectedUsageLimits.getMaxElementaryActionsPerTso());
// check instant with no limits
assertEquals(new RaUsageLimits(), crac.getRaUsageLimits(preventiveInstant));
// --------------------------
// --- test Contingencies ---
// --------------------------
// check that Contingencies are present
assertNotNull(crac.getContingency("contingency1Id"));
assertNotNull(crac.getContingency("contingency2Id"));
// check network elements
assertEquals(1, crac.getContingency("contingency1Id").getElements().size());
assertEquals("ne1Id", crac.getContingency("contingency1Id").getElements().iterator().next().getId());
assertEquals(2, crac.getContingency("contingency2Id").getElements().size());
// ----------------------
// --- test FlowCnecs ---
// ----------------------
// check that Cnecs are present
assertNotNull(crac.getFlowCnec("cnec1prevId"));
assertNotNull(crac.getFlowCnec("cnec1outageId"));
assertNotNull(crac.getFlowCnec("cnec2prevId"));
assertNotNull(crac.getFlowCnec("cnec3prevId"));
assertNotNull(crac.getFlowCnec("cnec3autoId"));
assertNotNull(crac.getFlowCnec("cnec3curId"));
assertNotNull(crac.getFlowCnec("cnec4prevId"));
// check network element
assertEquals("ne2Id", crac.getFlowCnec("cnec3prevId").getNetworkElement().getId());
assertEquals("ne2Name", crac.getFlowCnec("cnec3prevId").getNetworkElement().getName());
assertEquals("ne4Id", crac.getFlowCnec("cnec1outageId").getNetworkElement().getId());
assertEquals("ne4Id", crac.getFlowCnec("cnec1outageId").getNetworkElement().getName());
// check instants and contingencies
assertEquals(preventiveInstant, crac.getFlowCnec("cnec1prevId").getState().getInstant());
assertTrue(crac.getFlowCnec("cnec1prevId").getState().getContingency().isEmpty());
assertEquals(curativeInstant, crac.getFlowCnec("cnec3curId").getState().getInstant());
assertEquals("contingency2Id", crac.getFlowCnec("cnec3curId").getState().getContingency().get().getId());
assertEquals(autoInstant, crac.getFlowCnec("cnec3autoId").getState().getInstant());
assertEquals("contingency2Id", crac.getFlowCnec("cnec3autoId").getState().getContingency().get().getId());
// check monitored and optimized
assertFalse(crac.getFlowCnec("cnec3prevId").isOptimized());
assertTrue(crac.getFlowCnec("cnec3prevId").isMonitored());
assertTrue(crac.getFlowCnec("cnec4prevId").isOptimized());
assertTrue(crac.getFlowCnec("cnec4prevId").isMonitored());
// check operators
assertEquals("operator1", crac.getFlowCnec("cnec1prevId").getOperator());
assertEquals("operator1", crac.getFlowCnec("cnec1outageId").getOperator());
assertEquals("operator2", crac.getFlowCnec("cnec2prevId").getOperator());
assertEquals("operator3", crac.getFlowCnec("cnec3prevId").getOperator());
assertEquals("operator4", crac.getFlowCnec("cnec4prevId").getOperator());
// check iMax and nominal voltage
assertEquals(2000., crac.getFlowCnec("cnec2prevId").getIMax(TwoSides.ONE), 1e-3);
assertEquals(2000., crac.getFlowCnec("cnec2prevId").getIMax(TwoSides.TWO), 1e-3);
assertEquals(380., crac.getFlowCnec("cnec2prevId").getNominalVoltage(TwoSides.ONE), 1e-3);
assertEquals(220., crac.getFlowCnec("cnec2prevId").getNominalVoltage(TwoSides.TWO), 1e-3);
assertEquals(Double.NaN, crac.getFlowCnec("cnec1prevId").getIMax(TwoSides.ONE), 1e-3);
assertEquals(1000., crac.getFlowCnec("cnec1prevId").getIMax(TwoSides.TWO), 1e-3);
assertEquals(220., crac.getFlowCnec("cnec1prevId").getNominalVoltage(TwoSides.ONE), 1e-3);
assertEquals(220., crac.getFlowCnec("cnec1prevId").getNominalVoltage(TwoSides.TWO), 1e-3);
// check threshold
assertEquals(1, crac.getFlowCnec("cnec4prevId").getThresholds().size());
BranchThreshold threshold = crac.getFlowCnec("cnec4prevId").getThresholds().iterator().next();
assertEquals(Unit.MEGAWATT, threshold.getUnit());
assertEquals(TwoSides.ONE, threshold.getSide());
assertTrue(threshold.min().isEmpty());
assertEquals(500., threshold.max().orElse(0.0), 1e-3);
assertEquals(4, crac.getFlowCnec("cnec2prevId").getThresholds().size());
// ----------------------
// --- test AngleCnec ---
// ----------------------
AngleCnec angleCnec = crac.getAngleCnec("angleCnecId");
assertNotNull(angleCnec);
assertEquals("eneId", angleCnec.getExportingNetworkElement().getId());
assertEquals("ineId", angleCnec.getImportingNetworkElement().getId());
assertEquals(curativeInstant, angleCnec.getState().getInstant());
assertEquals("contingency1Id", angleCnec.getState().getContingency().get().getId());
assertFalse(angleCnec.isOptimized());
assertTrue(angleCnec.isMonitored());
assertEquals("operator1", angleCnec.getOperator());
assertEquals(-90., angleCnec.getLowerBound(Unit.DEGREE).orElseThrow(), 1e-3);
assertEquals(90., angleCnec.getUpperBound(Unit.DEGREE).orElseThrow(), 1e-3);
// ----------------------
// --- test VoltageCnec ---
// ----------------------
VoltageCnec voltageCnec = crac.getVoltageCnec("voltageCnecId");
assertNotNull(voltageCnec);
assertEquals("voltageCnecNeId", voltageCnec.getNetworkElement().getId());
assertEquals(curativeInstant, voltageCnec.getState().getInstant());
assertEquals("contingency1Id", voltageCnec.getState().getContingency().get().getId());
assertFalse(voltageCnec.isOptimized());
assertTrue(voltageCnec.isMonitored());
assertEquals("operator1", voltageCnec.getOperator());
assertEquals(381, voltageCnec.getLowerBound(Unit.KILOVOLT).orElseThrow(), 1e-3);
// ---------------------------
// --- test NetworkActions ---
// ---------------------------
// check that NetworkAction are present
assertNotNull(crac.getNetworkAction("pstSetpointRaId"));
assertNotNull(crac.getNetworkAction("injectionSetpointRaId"));
assertNotNull(crac.getNetworkAction("complexNetworkActionId"));
assertNotNull(crac.getNetworkAction("switchPairRaId"));
assertNotNull(crac.getNetworkAction("complexNetworkAction2Id"));
// check elementaryActions
assertEquals(1, crac.getNetworkAction("pstSetpointRaId").getElementaryActions().size());
Action pstAction = crac.getNetworkAction("pstSetpointRaId").getElementaryActions().iterator().next();
assertTrue(pstAction instanceof PhaseTapChangerTapPositionAction);
assertEquals("pst", ((PhaseTapChangerTapPositionAction) pstAction).getTransformerId());
assertEquals(1, crac.getNetworkAction("injectionSetpointRaId").getElementaryActions().size());
Action ra1Action = crac.getNetworkAction("injectionSetpointRaId").getElementaryActions().iterator().next();
assertTrue(ra1Action instanceof GeneratorAction);
assertEquals("injection", ((GeneratorAction) ra1Action).getGeneratorId());
assertEquals(2, crac.getNetworkAction("complexNetworkActionId").getElementaryActions().size());
List<Action> raComplexActions = crac.getNetworkAction("complexNetworkActionId").getElementaryActions().stream().toList();
assertTrue(raComplexActions.get(0) instanceof PhaseTapChangerTapPositionAction);
assertEquals("pst", ((PhaseTapChangerTapPositionAction) raComplexActions.get(0)).getTransformerId());
assertTrue(raComplexActions.get(1) instanceof TerminalsConnectionAction);
assertEquals("ne1Id", ((TerminalsConnectionAction) raComplexActions.get(1)).getElementId());
assertEquals(4, crac.getNetworkAction("complexNetworkAction2Id").getElementaryActions().size());
List<Action> raComplex2Actions = crac.getNetworkAction("complexNetworkAction2Id").getElementaryActions().stream().toList();
assertTrue(raComplex2Actions.get(0) instanceof DanglingLineAction);
assertEquals("DL1", ((DanglingLineAction) raComplex2Actions.get(0)).getDanglingLineId());
assertTrue(raComplex2Actions.get(1) instanceof LoadAction);
assertEquals("LD1", ((LoadAction) raComplex2Actions.get(1)).getLoadId());
assertTrue(raComplex2Actions.get(2) instanceof SwitchAction);
assertEquals("BR1", ((SwitchAction) raComplex2Actions.get(2)).getSwitchId());
assertTrue(raComplex2Actions.get(3) instanceof ShuntCompensatorPositionAction);
assertEquals("SC1", ((ShuntCompensatorPositionAction) raComplex2Actions.get(3)).getShuntCompensatorId());
// check onInstant usage rule
assertEquals(1, crac.getNetworkAction("complexNetworkActionId").getUsageRules().size());
OnInstant onInstant = crac.getNetworkAction("complexNetworkActionId").getUsageRules().stream()
.filter(ur -> ur instanceof OnInstant)
.map(ur -> (OnInstant) ur)
.findAny().orElse(null);
assertNotNull(onInstant);
assertEquals(preventiveInstant, onInstant.getInstant());
assertEquals(FORCED, onInstant.getUsageMethod());
// check several usage rules
assertEquals(2, crac.getNetworkAction("pstSetpointRaId").getUsageRules().size());
// check onContingencyState usage Rule (curative)
OnContingencyState onContingencyState = crac.getNetworkAction("pstSetpointRaId").getUsageRules().stream()
.filter(ur -> ur instanceof OnContingencyState)
.map(ur -> (OnContingencyState) ur)
.findAny().orElse(null);
assertNotNull(onContingencyState);
assertEquals("contingency1Id", onContingencyState.getContingency().getId());
assertEquals(curativeInstant, onContingencyState.getInstant());
assertEquals(FORCED, onContingencyState.getUsageMethod());
// check automaton OnFlowConstraint usage rule
assertEquals(1, crac.getNetworkAction("injectionSetpointRaId").getUsageRules().size());
UsageRule injectionSetpointRaUsageRule = crac.getNetworkAction("injectionSetpointRaId").getUsageRules().iterator().next();
assertTrue(injectionSetpointRaUsageRule instanceof OnConstraint<?>);
OnConstraint<?> onFlowConstraint1 = (OnConstraint<?>) injectionSetpointRaUsageRule;
assertEquals("cnec3autoId", onFlowConstraint1.getCnec().getId());
assertTrue(onFlowConstraint1.getCnec() instanceof FlowCnec);
assertEquals(autoInstant, onFlowConstraint1.getInstant());
assertEquals(FORCED, onFlowConstraint1.getUsageMethod());
// test SwitchPair
assertEquals(1, crac.getNetworkAction("switchPairRaId").getElementaryActions().size());
assertTrue(crac.getNetworkAction("switchPairRaId").getElementaryActions().iterator().next() instanceof SwitchPair);
SwitchPair switchPair = (SwitchPair) crac.getNetworkAction("switchPairRaId").getElementaryActions().iterator().next();
assertEquals("to-open", switchPair.getSwitchToOpen().getId());
assertEquals("to-close", switchPair.getSwitchToClose().getId());
// ----------------------------
// --- test PstRangeActions ---
// ----------------------------
// check that RangeActions are present
assertNotNull(crac.getRangeAction("pstRange1Id"));
assertNotNull(crac.getRangeAction("pstRange2Id"));
assertNotNull(crac.getRangeAction("pstRange3Id"));
assertNotNull(crac.getRangeAction("pstRange5Id"));
// check groupId
assertTrue(crac.getRangeAction("pstRange1Id").getGroupId().isEmpty());
assertEquals("group-1-pst", crac.getRangeAction("pstRange2Id").getGroupId().orElseThrow());
assertEquals("group-3-pst", crac.getRangeAction("pstRange3Id").getGroupId().orElseThrow());
// check Tap Range
assertEquals(2, crac.getPstRangeAction("pstRange1Id").getRanges().size());
TapRange absRange = crac.getPstRangeAction("pstRange1Id").getRanges().stream()
.filter(tapRange -> tapRange.getRangeType().equals(RangeType.ABSOLUTE))
.findAny().orElse(null);
TapRange relRange = crac.getPstRangeAction("pstRange1Id").getRanges().stream()
.filter(tapRange -> tapRange.getRangeType().equals(RangeType.RELATIVE_TO_INITIAL_NETWORK))
.findAny().orElse(null);
assertNotNull(absRange);
assertEquals(1, absRange.getMinTap());
assertEquals(7, absRange.getMaxTap());
assertNotNull(relRange);
assertEquals(-3, relRange.getMinTap());
assertEquals(3, relRange.getMaxTap());
assertEquals(Unit.TAP, relRange.getUnit());
// check OnFlowConstraint usage rule
assertEquals(1, crac.getPstRangeAction("pstRange2Id").getUsageRules().size());
UsageRule pstRange2UsageRule = crac.getPstRangeAction("pstRange2Id").getUsageRules().iterator().next();
assertTrue(pstRange2UsageRule instanceof OnConstraint<?>);
OnConstraint<?> onFlowConstraint2 = (OnConstraint<?>) pstRange2UsageRule;
assertEquals(preventiveInstant, onFlowConstraint2.getInstant());
assertSame(crac.getCnec("cnec3prevId"), onFlowConstraint2.getCnec());
assertTrue(onFlowConstraint2.getCnec() instanceof FlowCnec);
assertEquals(AVAILABLE, onFlowConstraint2.getUsageMethod());
// check Tap Range
assertEquals(3, crac.getPstRangeAction("pstRange2Id").getRanges().size());
absRange = crac.getPstRangeAction("pstRange2Id").getRanges().stream()
.filter(tapRange -> tapRange.getRangeType().equals(RangeType.ABSOLUTE))
.findAny().orElse(null);
relRange = crac.getPstRangeAction("pstRange2Id").getRanges().stream()
.filter(tapRange -> tapRange.getRangeType().equals(RangeType.RELATIVE_TO_INITIAL_NETWORK))
.findAny().orElse(null);
TapRange relTimestampRange = crac.getPstRangeAction("pstRange2Id").getRanges().stream()
.filter(tapRange -> tapRange.getRangeType().equals(RangeType.RELATIVE_TO_PREVIOUS_TIME_STEP))
.findAny().orElse(null);
assertNotNull(absRange);
assertEquals(-4, absRange.getMinTap());
assertEquals(3, absRange.getMaxTap());
assertNotNull(relRange);
assertEquals(-5, relRange.getMinTap());
assertEquals(1, relRange.getMaxTap());
assertNotNull(relTimestampRange);
assertEquals(-2, relTimestampRange.getMinTap());
assertEquals(5, relTimestampRange.getMaxTap());
assertEquals(Unit.TAP, relRange.getUnit());
assertEquals(Unit.TAP, relTimestampRange.getUnit());
// check OnAngleConstraint usage rule
assertEquals(1, crac.getPstRangeAction("pstRange3Id").getUsageRules().size());
UsageRule pstRange3UsageRule = crac.getPstRangeAction("pstRange3Id").getUsageRules().iterator().next();
assertTrue(pstRange3UsageRule instanceof OnConstraint<?>);
OnConstraint<?> onConstraint = (OnConstraint<?>) pstRange3UsageRule;
assertEquals(curativeInstant, onConstraint.getInstant());
assertSame(crac.getCnec("angleCnecId"), onConstraint.getCnec());
assertTrue(onConstraint.getCnec() instanceof AngleCnec);
assertEquals(AVAILABLE, onConstraint.getUsageMethod());
// check OnVoltageConstraint usage rule
Set<UsageRule> pstRange4IdUsageRules = crac.getPstRangeAction("pstRange4Id").getUsageRules();
assertEquals(1, pstRange4IdUsageRules.size());
UsageRule pstRange4IdFirstUsageRules = pstRange4IdUsageRules.iterator().next();
assertTrue(pstRange4IdFirstUsageRules instanceof OnConstraint<?>);
OnConstraint<?> onVoltageConstraint = (OnConstraint<?>) pstRange4IdFirstUsageRules;
assertEquals(curativeInstant, onVoltageConstraint.getInstant());
assertSame(crac.getCnec("voltageCnecId"), onVoltageConstraint.getCnec());
assertTrue(onVoltageConstraint.getCnec() instanceof VoltageCnec);
assertEquals(AVAILABLE, onVoltageConstraint.getUsageMethod());
// check Usage Method for pst5
PstRangeAction pst5 = crac.getPstRangeAction("pstRange5Id");
assertEquals(2, pst5.getUsageRules().size());
List<UsageRule> onFlowConstrainRule = pst5.getUsageRules().stream().filter(usageRule -> usageRule instanceof OnConstraint<?>).filter(oc -> ((OnConstraint<?>) oc).getCnec() instanceof FlowCnec).toList();
assertEquals(1, onFlowConstrainRule.size());
assertEquals(UsageMethod.AVAILABLE, onFlowConstrainRule.get(0).getUsageMethod(crac.getPreventiveState()));
List<UsageRule> onInstantRule = pst5.getUsageRules().stream().filter(usageRule -> usageRule instanceof OnInstant).toList();
assertEquals(1, onInstantRule.size());
assertEquals(UsageMethod.FORCED, onInstantRule.get(0).getUsageMethod(crac.getPreventiveState()));
// asserts that FORCED UsageMethod prevails over AVAILABLE
assertEquals(UsageMethod.FORCED, pst5.getUsageMethod(crac.getPreventiveState()));
// -----------------------------
// --- test HvdcRangeActions ---
// -----------------------------
assertNotNull(crac.getRangeAction("hvdcRange1Id"));
assertNotNull(crac.getRangeAction("hvdcRange2Id"));
// check groupId
assertTrue(crac.getRangeAction("hvdcRange1Id").getGroupId().isEmpty());
assertEquals("group-1-hvdc", crac.getRangeAction("hvdcRange2Id").getGroupId().orElseThrow());
// check preventive OnFlowConstraint usage rule
assertEquals(3, crac.getHvdcRangeAction("hvdcRange2Id").getUsageRules().size());
OnConstraint<?> onFlowConstraint3 = (OnConstraint<?>) crac.getHvdcRangeAction("hvdcRange2Id").getUsageRules().stream().filter(OnConstraint.class::isInstance).filter(oc -> ((OnConstraint<?>) oc).getCnec() instanceof FlowCnec).findAny().orElseThrow();
assertEquals(preventiveInstant, onFlowConstraint3.getInstant());
assertEquals(AVAILABLE, onFlowConstraint3.getUsageMethod());
assertSame(crac.getCnec("cnec3curId"), onFlowConstraint3.getCnec());
assertTrue(onFlowConstraint3.getCnec() instanceof FlowCnec);
// check Hvdc range
assertEquals(1, crac.getHvdcRangeAction("hvdcRange1Id").getRanges().size());
StandardRange hvdcRange = crac.getHvdcRangeAction("hvdcRange1Id").getRanges().get(0);
assertEquals(-1000, hvdcRange.getMin(), 1e-3);
assertEquals(1000, hvdcRange.getMax(), 1e-3);
assertEquals(Unit.MEGAWATT, hvdcRange.getUnit());
// Check OnFlowConstraintInCountry usage rules
Set<UsageRule> usageRules = crac.getHvdcRangeAction("hvdcRange1Id").getUsageRules();
assertEquals(1, usageRules.size());
UsageRule hvdcRange1UsageRule = usageRules.iterator().next();
assertTrue(hvdcRange1UsageRule instanceof OnFlowConstraintInCountry);
OnFlowConstraintInCountry ur = (OnFlowConstraintInCountry) hvdcRange1UsageRule;
assertEquals(preventiveInstant, ur.getInstant());
assertEquals(Country.FR, ur.getCountry());
assertEquals(AVAILABLE, ur.getUsageMethod());
// ---------------------------------
// --- test InjectionRangeAction ---
// ---------------------------------
assertNotNull(crac.getInjectionRangeAction("injectionRange1Id"));
assertEquals("injectionRange1Name", crac.getInjectionRangeAction("injectionRange1Id").getName());
assertNull(crac.getInjectionRangeAction("injectionRange1Id").getOperator());
assertTrue(crac.getInjectionRangeAction("injectionRange1Id").getGroupId().isEmpty());
Map<NetworkElement, Double> networkElementAndKeys = crac.getInjectionRangeAction("injectionRange1Id").getInjectionDistributionKeys();
assertEquals(2, networkElementAndKeys.size());
assertEquals(1., networkElementAndKeys.entrySet().stream().filter(e -> e.getKey().getId().equals("generator1Id")).findAny().orElseThrow().getValue(), 1e-3);
assertEquals(-1., networkElementAndKeys.entrySet().stream().filter(e -> e.getKey().getId().equals("generator2Id")).findAny().orElseThrow().getValue(), 1e-3);
assertEquals("generator2Name", networkElementAndKeys.entrySet().stream().filter(e -> e.getKey().getId().equals("generator2Id")).findAny().orElseThrow().getKey().getName());
assertEquals(2, crac.getInjectionRangeAction("injectionRange1Id").getRanges().size());
// Check OnFlowConstraintInCountry usage rules
usageRules = crac.getInjectionRangeAction("injectionRange1Id").getUsageRules();
assertEquals(2, usageRules.size());
ur = (OnFlowConstraintInCountry) usageRules.stream().filter(OnFlowConstraintInCountry.class::isInstance).findAny().orElseThrow();
assertEquals(curativeInstant, ur.getInstant());
assertEquals(Country.ES, ur.getCountry());
assertTrue(ur.getContingency().isPresent());
assertEquals("contingency2Id", ur.getContingency().get().getId());
// ---------------------------------
// --- test CounterTradeRangeAction ---
// ---------------------------------
assertNotNull(crac.getCounterTradeRangeAction("counterTradeRange1Id"));
assertEquals("counterTradeRange1Name", crac.getCounterTradeRangeAction("counterTradeRange1Id").getName());
assertNull(crac.getCounterTradeRangeAction("counterTradeRange1Id").getOperator());
assertTrue(crac.getCounterTradeRangeAction("counterTradeRange1Id").getGroupId().isEmpty());
assertEquals(2, crac.getCounterTradeRangeAction("counterTradeRange1Id").getRanges().size());
assertEquals(Country.FR, crac.getCounterTradeRangeAction("counterTradeRange1Id").getExportingCountry());
assertEquals(Country.DE, crac.getCounterTradeRangeAction("counterTradeRange1Id").getImportingCountry());
// Check OnFlowConstraintInCountry usage rules
usageRules = crac.getRemedialAction("counterTradeRange1Id").getUsageRules();
assertEquals(2, usageRules.size());
ur = (OnFlowConstraintInCountry) usageRules.stream().filter(OnFlowConstraintInCountry.class::isInstance).findAny().orElseThrow();
assertEquals(curativeInstant, ur.getInstant());
assertEquals(Country.ES, ur.getCountry());
assertEquals(AVAILABLE, ur.getUsageMethod());
}
@Test
void testImportNotJsonFile() {
InputStream inputStream = Mockito.mock(InputStream.class);
assertFalse(new JsonImport().exists("file.xml", inputStream));
}
@Test
void testImportEmptyCrac() throws IOException {
Network network = Mockito.mock(Network.class);
Crac crac = Crac.read("emptyCrac.json", CracImportExportTest.class.getResourceAsStream("/emptyCrac.json"), network);
assertNotNull(crac);
// round-trip
Crac roundTripCrac = implicitJsonRoundTrip(crac, network);
assertTrue(roundTripCrac.getTimestamp().isEmpty());
assertTrue(roundTripCrac.getContingencies().isEmpty());
assertTrue(roundTripCrac.getRemedialActions().isEmpty());
assertTrue(roundTripCrac.getCnecs().isEmpty());
}
@Test
void testImportCracWithErrors() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> new JsonImport().exists("cracWithErrors.json", CracImportExportTest.class.getResourceAsStream("/cracWithErrors.json")));
assertEquals("JSON file is not a valid CRAC v2.5. Reasons: /instants/3/kind: does not have a value in the enumeration [\"PREVENTIVE\", \"OUTAGE\", \"AUTO\", \"CURATIVE\"]; /contingencies/1/networkElementsIds/0: integer found, string expected; /contingencies/1/networkElementsIds/1: integer found, string expected; /contingencies/2: required property 'networkElementsIds' not found", exception.getMessage());
}
}