CracImplTest.java
/*
* Copyright (c) 2019, 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.impl;
import com.powsybl.contingency.BranchContingency;
import com.powsybl.contingency.Contingency;
import com.powsybl.contingency.ContingencyElement;
import com.powsybl.contingency.ContingencyElementType;
import com.powsybl.iidm.network.Country;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.PhysicalParameter;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.ContingencyAdder;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.InstantKind;
import com.powsybl.openrao.data.crac.api.NetworkElement;
import com.powsybl.openrao.data.crac.api.RaUsageLimits;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.rangeaction.HvdcRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.HvdcRangeActionAdder;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeActionAdder;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
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.FlowCnecAdder;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.crac.api.cnec.VoltageCnec;
import com.powsybl.openrao.data.crac.api.networkaction.ActionType;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkActionAdder;
import com.powsybl.openrao.data.crac.api.range.RangeType;
import com.powsybl.openrao.data.crac.api.usagerule.UsageMethod;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
/**
* General test file
*
* @author Viktor Terrier {@literal <viktor.terrier at rte-france.com>}
*/
class CracImplTest {
private static final String PREVENTIVE_INSTANT_ID = "preventive";
private static final String OUTAGE_INSTANT_ID = "outage";
private static final String AUTO_INSTANT_ID = "auto";
private static final String CURATIVE_INSTANT_ID = "curative";
private CracImpl crac;
private Instant preventiveInstant;
private Instant outageInstant;
private Instant autoInstant;
private Instant curativeInstant;
private State state1;
private State state2;
private RangeAction<?> ra1;
private RangeAction<?> ra2;
private RangeAction<?> ra3;
private RangeAction<?> ra4;
private RangeAction<?> ra5;
private RangeAction<?> ra6;
private RangeAction<?> ra7;
private RangeAction<?> ra8;
private RangeAction<?> ra9;
private RangeAction<?> ra10;
private ContingencyElementType getRandomTypeContingency() {
return ContingencyElementType.LINE;
}
private ContingencyElement getRandomTypeContingencyElement(String id) {
return new BranchContingency(id);
}
@BeforeEach
public void setUp() {
crac = new CracImpl("test-crac")
.newInstant(PREVENTIVE_INSTANT_ID, InstantKind.PREVENTIVE)
.newInstant(OUTAGE_INSTANT_ID, InstantKind.OUTAGE)
.newInstant(AUTO_INSTANT_ID, InstantKind.AUTO)
.newInstant(CURATIVE_INSTANT_ID, InstantKind.CURATIVE);
preventiveInstant = crac.getInstant(PREVENTIVE_INSTANT_ID);
outageInstant = crac.getInstant(OUTAGE_INSTANT_ID);
autoInstant = crac.getInstant(AUTO_INSTANT_ID);
curativeInstant = crac.getInstant(CURATIVE_INSTANT_ID);
}
@Test
void testAddNetworkElementWithIdAndName() {
NetworkElement networkElement = crac.addNetworkElement("neID", "neName");
assertEquals(1, crac.getNetworkElements().size());
assertNotNull(crac.getNetworkElement("neID"));
assertSame(networkElement, crac.getNetworkElement("neID"));
}
@Test
void testAddNetworkElementWithIdAndNameFail() {
crac.addNetworkElement("neID", "neName");
try {
crac.addNetworkElement("neID", "neName-fail");
fail();
} catch (OpenRaoException e) {
assertEquals("A network element with the same ID (neID) but a different name already exists.", e.getMessage());
}
}
@Test
void testAddNetworkElementWithIdAndNameTwice() {
NetworkElement networkElement1 = crac.addNetworkElement("neID", "neName");
NetworkElement networkElement2 = crac.addNetworkElement("neID", "neName");
assertEquals(1, crac.getNetworkElements().size());
assertNotNull(crac.getNetworkElement("neID"));
assertSame(networkElement1, networkElement2);
assertSame(networkElement1, crac.getNetworkElement("neID"));
}
@Test
void testGetContingency() {
assertEquals(0, crac.getContingencies().size());
}
@Test
void testAddContingency() {
assertEquals(0, crac.getContingencies().size());
crac.addContingency(new Contingency("contingency-1", "co-name", Collections.singletonList(getRandomTypeContingencyElement("ne1"))));
assertEquals(1, crac.getContingencies().size());
assertNotNull(crac.getContingency("contingency-1"));
crac.addContingency(new Contingency("contingency-2", "co-name", Collections.singletonList(getRandomTypeContingencyElement("ne1"))));
assertEquals(2, crac.getContingencies().size());
crac.addContingency(new Contingency("contingency-3", "co-name", Collections.singletonList(getRandomTypeContingencyElement("ne3"))));
assertEquals(3, crac.getContingencies().size());
assertNotNull(crac.getContingency("contingency-3"));
assertNull(crac.getContingency("contingency-fail"));
}
@Test
void testStatesAndInstantsInitialization() {
assertEquals(0, crac.getContingencies().size());
assertEquals(0, crac.getStates().size());
}
@Test
void testGetStateWithNotExistingContingencyId() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.getState("fail-contingency", curativeInstant));
assertEquals("Contingency fail-contingency does not exist, as well as the related state.", exception.getMessage());
}
@Test
void testGetStateWithNotExistingContingency() {
Contingency contingency = crac.newContingency()
.withId("co")
.withName("co-name")
.withContingencyElement("ne", getRandomTypeContingency())
.add();
assertNull(crac.getState(contingency, curativeInstant));
}
@Test
void testGetCnecandGetFlowCnec() {
crac.newContingency().withId("co").withContingencyElement("ne-co", getRandomTypeContingency()).add();
crac.newFlowCnec()
.withId("cnec-id")
.withName("cnec-name")
.withNetworkElement("ne")
.withOperator("operator")
.withOptimized(true)
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co")
.newThreshold().withMin(-1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
assertNotNull(crac.getFlowCnec("cnec-id"));
assertNotNull(crac.getCnec("cnec-id"));
}
@Test
void testAddPstRangeActionWithNoConflict() {
PstRangeAction rangeAction = Mockito.mock(PstRangeAction.class);
when(rangeAction.getId()).thenReturn("rangeAction");
State state = Mockito.mock(State.class);
when(state.getContingency()).thenReturn(Optional.empty());
assertEquals(0, crac.getPstRangeActions().size());
assertEquals(0, crac.getRangeActions().size());
assertEquals(0, crac.getRemedialActions().size());
crac.addPstRangeAction(rangeAction);
assertEquals(1, crac.getPstRangeActions().size());
assertEquals(1, crac.getRangeActions().size());
assertEquals(1, crac.getRemedialActions().size());
assertNotNull(crac.getRemedialAction("rangeAction"));
}
@Test
void testAddHvdcRangeActionWithNoConflict() {
HvdcRangeAction rangeAction = Mockito.mock(HvdcRangeAction.class);
when(rangeAction.getId()).thenReturn("rangeAction");
State state = Mockito.mock(State.class);
when(state.getContingency()).thenReturn(Optional.empty());
assertEquals(0, crac.getHvdcRangeActions().size());
assertEquals(0, crac.getRangeActions().size());
assertEquals(0, crac.getRemedialActions().size());
crac.addHvdcRangeAction(rangeAction);
assertEquals(1, crac.getHvdcRangeActions().size());
assertEquals(1, crac.getRangeActions().size());
assertEquals(1, crac.getRemedialActions().size());
assertNotNull(crac.getRemedialAction("rangeAction"));
}
@Test
void testSafeRemoveNetworkElements() {
crac.newContingency().withId("co").withContingencyElement("ne1", getRandomTypeContingency()).withContingencyElement("ne2", getRandomTypeContingency()).add();
crac.newFlowCnec()
.withId("cnec")
.withNetworkElement("ne3")
.withOperator("operator")
.withInstant(PREVENTIVE_INSTANT_ID)
.newThreshold().withMin(-1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
crac.newNetworkAction()
.withId("na")
.withOperator("operator")
.newTerminalsConnectionAction().withActionType(ActionType.OPEN).withNetworkElement("ne4").add()
.newSwitchAction().withActionType(ActionType.OPEN).withNetworkElement("ne5").add()
.add();
crac.addNetworkElement("ne6", "ne6");
crac.addNetworkElement("ne7", "ne7");
assertNotNull(crac.getRemedialAction("na"));
assertNotNull(crac.getNetworkAction("na"));
assertEquals(5, crac.getNetworkElements().size());
crac.safeRemoveNetworkElements(Set.of("ne3", "ne4", "ne5", "ne6"));
assertEquals(4, crac.getNetworkElements().size());
assertNotNull(crac.getNetworkElement("ne3"));
assertNotNull(crac.getNetworkElement("ne4"));
assertNotNull(crac.getNetworkElement("ne5"));
assertNull(crac.getNetworkElement("ne6"));
assertNotNull(crac.getNetworkElement("ne7"));
}
@Test
void testSafeRemoveStates() {
Contingency contingency1 = crac.newContingency()
.withId("co1")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
Contingency contingency2 = crac.newContingency()
.withId("co2")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
State curative1 = crac.addState(contingency1, curativeInstant);
State auto1 = crac.addState(contingency1, autoInstant);
State curative2 = crac.addState(contingency2, curativeInstant);
State auto2 = crac.addState(contingency1, outageInstant);
crac.addState(contingency2, outageInstant);
crac.newFlowCnec()
.withId("cnec")
.withNetworkElement("anyNetworkElement")
.withOperator("operator")
.withContingency("co1")
.withInstant(CURATIVE_INSTANT_ID)
.newThreshold().withMin(-1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
crac.newNetworkAction()
.withId("ra")
.withOperator("operator")
.newPhaseTapChangerTapPositionAction().withNetworkElement("anyPst").withTapPosition(8).add()
.newOnContingencyStateUsageRule()
.withContingency("co1")
.withInstant(AUTO_INSTANT_ID)
.withUsageMethod(UsageMethod.AVAILABLE)
.add()
.newOnContingencyStateUsageRule()
.withContingency("co2")
.withInstant(CURATIVE_INSTANT_ID)
.withUsageMethod(UsageMethod.FORCED)
.add()
.add();
assertNotNull(crac.getRemedialAction("ra"));
assertNotNull(crac.getNetworkAction("ra"));
assertEquals(5, crac.getStates().size());
crac.safeRemoveStates(Set.of(curative1.getId(), auto1.getId(), curative2.getId(), auto2.getId()));
assertEquals(4, crac.getStates().size());
assertNotNull(crac.getState(contingency1, curativeInstant));
assertNotNull(crac.getState(contingency1, curativeInstant));
assertNotNull(crac.getState(contingency2, curativeInstant));
assertNull(crac.getState(contingency2, autoInstant));
assertNotNull(crac.getState(contingency2, curativeInstant));
}
@Test
void testContingencyAdder() {
ContingencyAdder contingencyAdder = crac.newContingency();
assertInstanceOf(ContingencyAdderImpl.class, contingencyAdder);
assertSame(crac, ((ContingencyAdderImpl) contingencyAdder).owner);
}
@Test
void testRemoveContingency() {
crac.newContingency().withId("co1").withContingencyElement("ne1", getRandomTypeContingency()).add();
crac.newContingency().withId("co2").withContingencyElement("ne2", getRandomTypeContingency()).add();
assertEquals(2, crac.getContingencies().size());
assertEquals(0, crac.getNetworkElements().size());
crac.removeContingency("co2");
assertEquals(1, crac.getContingencies().size());
assertEquals(0, crac.getNetworkElements().size());
assertNotNull(crac.getContingency("co1"));
assertNull(crac.getContingency("co2"));
}
@Test
void testRemoveUsedContingencyError() {
crac.newContingency()
.withId("co1")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
crac.newFlowCnec()
.withId("cnec")
.withNetworkElement("anyNetworkElement")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
assertEquals(1, crac.getContingencies().size());
try {
crac.removeContingency("co1");
fail();
} catch (OpenRaoException e) {
// expected behaviour
}
assertEquals(1, crac.getContingencies().size());
assertNotNull(crac.getContingency("co1"));
}
@Test
void testRemoveUsedContingencyError2() {
crac.newContingency()
.withId("co1")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
crac.newNetworkAction()
.withId("na")
.withOperator("operator")
.newTerminalsConnectionAction().withNetworkElement("anyNetworkElement").withActionType(ActionType.CLOSE).add()
.newOnContingencyStateUsageRule().withInstant(CURATIVE_INSTANT_ID).withContingency("co1").withUsageMethod(UsageMethod.AVAILABLE).add()
.add();
assertEquals(1, crac.getContingencies().size());
try {
crac.removeContingency("co1");
fail();
} catch (OpenRaoException e) {
// expected behaviour
}
assertEquals(1, crac.getContingencies().size());
assertNotNull(crac.getContingency("co1"));
}
@Test
void testPreventiveState() {
assertNull(crac.getPreventiveState());
crac.addPreventiveState();
State state = crac.getPreventiveState();
assertNotNull(state);
assertEquals(preventiveInstant, state.getInstant());
assertTrue(state.getContingency().isEmpty());
crac.addPreventiveState();
assertSame(state, crac.getPreventiveState());
}
@Test
void testGetStatesFromContingency() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
Contingency contingency2 = new Contingency("co2", "co2", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
crac.addContingency(contingency1);
crac.addContingency(contingency2);
State curative1 = crac.addState(contingency1, curativeInstant);
State outage1 = crac.addState(contingency1, outageInstant);
State curative2 = crac.addState(contingency2, curativeInstant);
State auto2 = crac.addState(contingency2, autoInstant);
State outage2 = crac.addState(contingency2, outageInstant);
assertEquals(2, crac.getStates(contingency1).size());
assertTrue(crac.getStates(contingency1).containsAll(Set.of(curative1, outage1)));
assertEquals(3, crac.getStates(contingency2).size());
assertTrue(crac.getStates(contingency2).containsAll(Set.of(curative2, auto2, outage2)));
Contingency contingency3 = new Contingency("co3", "co3", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
assertTrue(crac.getStates(contingency3).isEmpty());
}
@Test
void testGetStatesFromInstant() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
Contingency contingency2 = new Contingency("co2", "co2", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
crac.addContingency(contingency1);
crac.addContingency(contingency2);
State curative1 = crac.addState(contingency1, curativeInstant);
State outage1 = crac.addState(contingency1, outageInstant);
State curative2 = crac.addState(contingency2, curativeInstant);
State auto2 = crac.addState(contingency2, autoInstant);
State outage2 = crac.addState(contingency2, outageInstant);
assertEquals(2, crac.getStates(outageInstant).size());
assertTrue(crac.getStates(curativeInstant).containsAll(Set.of(curative1, curative2)));
assertEquals(2, crac.getStates(outageInstant).size());
assertTrue(crac.getStates(outageInstant).containsAll(Set.of(outage1, outage2)));
assertEquals(1, crac.getStates(autoInstant).size());
assertTrue(crac.getStates(autoInstant).contains(auto2));
assertTrue(crac.getStates(preventiveInstant).isEmpty());
}
@Test
void testAddStateWithPreventiveError() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
crac.addContingency(contingency1);
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.addState(contingency1, preventiveInstant));
assertEquals("Impossible to add a preventive state with a contingency.", exception.getMessage());
}
@Test
void testAddSameStateTwice() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
crac.addContingency(contingency1);
State curative1 = crac.addState(contingency1, curativeInstant);
State curative1bis = crac.addState(contingency1, curativeInstant);
assertSame(curative1, curative1bis);
}
@Test
void testAddStateBeforecontingencyError() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(Mockito.mock(ContingencyElement.class)));
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.addState(contingency1, curativeInstant));
assertEquals("Please add co1 to crac first.", exception.getMessage());
}
@Test
void testFlowCnecAdder() {
FlowCnecAdder flowCnecAdder = crac.newFlowCnec();
assertInstanceOf(FlowCnecAdderImpl.class, flowCnecAdder);
assertSame(crac, ((FlowCnecAdderImpl) flowCnecAdder).owner);
}
@Test
void testGetCnecsFromState() {
crac.newContingency()
.withId("co1")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
crac.newContingency()
.withId("co2")
.withContingencyElement("anyNetworkElement", getRandomTypeContingency())
.add();
FlowCnec cnec1 = crac.newFlowCnec()
.withId("cnec1")
.withNetworkElement("anyNetworkElement")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
FlowCnec cnec2 = crac.newFlowCnec()
.withId("cnec2")
.withNetworkElement("anyNetworkElement")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
FlowCnec cnec3 = crac.newFlowCnec()
.withId("cnec3")
.withNetworkElement("anyNetworkElement")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("co2")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
State curative1 = crac.getState("co1", curativeInstant);
State outage2 = crac.getState("co2", outageInstant);
assertEquals(2, crac.getFlowCnecs(curative1).size());
assertEquals(2, crac.getCnecs(curative1).size());
assertTrue(crac.getFlowCnecs(curative1).containsAll(Set.of(cnec1, cnec2)));
assertTrue(crac.getCnecs(curative1).containsAll(Set.of(cnec1, cnec2)));
assertEquals(1, crac.getFlowCnecs(outage2).size());
assertEquals(1, crac.getCnecs(outage2).size());
assertTrue(crac.getFlowCnecs(outage2).contains(cnec3));
assertTrue(crac.getCnecs(outage2).contains(cnec3));
}
@Test
void testRemoveCnec() {
crac.newContingency()
.withId("co1")
.withContingencyElement("neCo", getRandomTypeContingency())
.add();
crac.newContingency()
.withId("co2")
.withContingencyElement("neCo", getRandomTypeContingency())
.add();
crac.newFlowCnec()
.withId("cnec1")
.withNetworkElement("ne1")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
crac.newFlowCnec()
.withId("cnec2")
.withNetworkElement("ne1")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
crac.newFlowCnec()
.withId("cnec3")
.withNetworkElement("ne2")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
crac.newFlowCnec()
.withId("cnec4")
.withNetworkElement("ne2")
.withInstant(OUTAGE_INSTANT_ID)
.withContingency("co1")
.newThreshold().withMax(1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
assertEquals(4, crac.getFlowCnecs().size());
crac.removeCnec("doesnt exist 1");
crac.removeFlowCnec("doesnt exist 2");
assertEquals(4, crac.getFlowCnecs().size());
crac.removeCnec("cnec1");
assertNull(crac.getCnec("cnec1"));
assertNotNull(crac.getNetworkElement("ne1")); // still used by cnec2
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by cnec3
crac.removeFlowCnec("cnec2");
assertNull(crac.getCnec("cnec2"));
assertNull(crac.getNetworkElement("ne1")); // unused
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by cnec3
assertNotNull(crac.getState("co1", outageInstant)); // state2, still used by cnec4
crac.removeFlowCnec("cnec3");
assertNull(crac.getCnec("cnec3"));
assertNotNull(crac.getNetworkElement("ne2")); // still used by cnec4
assertNull(crac.getState("co1", curativeInstant)); // unused
assertNotNull(crac.getState("co1", outageInstant)); // state2, still used by cnec4
crac.removeCnec("cnec4");
assertEquals(0, crac.getFlowCnecs().size());
assertEquals(0, crac.getNetworkElements().size());
assertEquals(1, crac.getContingency("co1").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(1, crac.getContingency("co2").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(0, crac.getStates().size());
}
@Test
void testRemovePstRangeAction() {
crac.newContingency().withId("co1").withContingencyElement("neCo", getRandomTypeContingency()).add();
crac.newContingency().withId("co2").withContingencyElement("neCo", getRandomTypeContingency()).add();
ra1 = crac.newPstRangeAction()
.withId("ra1")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra2 = crac.newPstRangeAction()
.withId("ra2")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra3 = crac.newPstRangeAction()
.withId("ra3")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra4 = crac.newPstRangeAction()
.withId("ra4")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
state1 = crac.getState("co1", curativeInstant);
state2 = crac.getState("co2", curativeInstant);
assertEquals(0, crac.getRangeActions(state1, UsageMethod.FORCED).size());
assertEquals(2, crac.getRangeActions(state1, UsageMethod.AVAILABLE).size());
assertTrue(crac.getRangeActions(state1, UsageMethod.AVAILABLE).containsAll(Set.of(ra1, ra3)));
assertEquals(2, crac.getRangeActions(state2, UsageMethod.FORCED).size());
assertTrue(crac.getRangeActions(state2, UsageMethod.FORCED).containsAll(Set.of(ra2, ra4)));
assertEquals(4, crac.getPstRangeActions().size());
assertEquals(4, crac.getRangeActions().size());
assertEquals(4, crac.getRemedialActions().size());
crac.removeRemedialAction("doesnt exist 1");
crac.removePstRangeAction("doesnt exist 2");
assertEquals(4, crac.getPstRangeActions().size());
crac.removeRemedialAction("ra1");
assertNull(crac.getRemedialAction("ra1"));
assertNotNull(crac.getNetworkElement("ne1")); // still used by ra2
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by ra3
crac.removePstRangeAction("ra2");
assertNull(crac.getRangeAction("ra2"));
assertNull(crac.getNetworkElement("ne1")); // unused
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by ra3
assertNotNull(crac.getState("co2", curativeInstant)); // state2, still used by RA4
crac.removePstRangeAction("ra3");
assertNull(crac.getPstRangeAction("ra3"));
assertNotNull(crac.getNetworkElement("ne2")); // still used by ra4
assertNull(crac.getState("co1", curativeInstant)); // unused
assertNotNull(crac.getState("co2", curativeInstant)); // state2, still used by ra4
crac.removeRemedialAction("ra4");
assertEquals(0, crac.getRemedialActions().size());
assertEquals(0, crac.getNetworkElements().size());
assertEquals(1, crac.getContingency("co1").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(1, crac.getContingency("co2").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(0, crac.getStates().size());
}
@Test
void testRemoveHvdcRangeAction() {
crac.newContingency().withId("co1").withContingencyElement("neCo", getRandomTypeContingency()).add();
crac.newContingency().withId("co2").withContingencyElement("neCo", getRandomTypeContingency()).add();
ra1 = crac.newHvdcRangeAction()
.withId("ra1")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra2 = crac.newHvdcRangeAction()
.withId("ra2")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra3 = crac.newHvdcRangeAction()
.withId("ra3")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra4 = crac.newHvdcRangeAction()
.withId("ra4")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
state1 = crac.getState("co1", curativeInstant);
state2 = crac.getState("co2", curativeInstant);
assertEquals(0, crac.getRangeActions(state1, UsageMethod.FORCED).size());
assertEquals(2, crac.getRangeActions(state1, UsageMethod.AVAILABLE).size());
assertTrue(crac.getRangeActions(state1, UsageMethod.AVAILABLE).containsAll(Set.of(ra1, ra3)));
assertEquals(2, crac.getRangeActions(state2, UsageMethod.FORCED).size());
assertTrue(crac.getRangeActions(state2, UsageMethod.FORCED).containsAll(Set.of(ra2, ra4)));
assertEquals(4, crac.getHvdcRangeActions().size());
assertEquals(4, crac.getRangeActions().size());
assertEquals(4, crac.getRemedialActions().size());
crac.removeRemedialAction("doesnt exist 1");
crac.removeHvdcRangeAction("doesnt exist 2");
assertEquals(4, crac.getHvdcRangeActions().size());
crac.removeRemedialAction("ra1");
assertNull(crac.getRemedialAction("ra1"));
assertNotNull(crac.getNetworkElement("ne1")); // still used by ra2
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by ra3
crac.removeHvdcRangeAction("ra2");
assertNull(crac.getRangeAction("ra2"));
assertNull(crac.getNetworkElement("ne1")); // unused
assertNotNull(crac.getState("co1", curativeInstant)); // state1, still used by ra3
assertNotNull(crac.getState("co2", curativeInstant)); // state2, still used by RA4
crac.removeHvdcRangeAction("ra3");
assertNull(crac.getHvdcRangeAction("ra3"));
assertNotNull(crac.getNetworkElement("ne2")); // still used by ra4
assertNull(crac.getState("co1", curativeInstant)); // unused
assertNotNull(crac.getState("co2", curativeInstant)); // state2, still used by ra4
crac.removeRemedialAction("ra4");
assertEquals(0, crac.getRemedialActions().size());
assertEquals(0, crac.getNetworkElements().size());
assertEquals(1, crac.getContingency("co1").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(1, crac.getContingency("co1").getElements().stream().filter(e -> Objects.equals(e.getId(), "neCo")).count());
assertEquals(0, crac.getStates().size());
}
@Test
void testFilterPstRangeActionUsageRules() {
crac.newContingency().withId("co1").withContingencyElement("neCo", getRandomTypeContingency()).add();
crac.newContingency().withId("co2").withContingencyElement("neCo", getRandomTypeContingency()).add();
ra1 = crac.newPstRangeAction()
.withId("ra1")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra2 = crac.newPstRangeAction()
.withId("ra2")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra3 = crac.newPstRangeAction()
.withId("ra3")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
ra4 = crac.newPstRangeAction()
.withId("ra4")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.withInitialTap(0)
.withTapToAngleConversionMap(Map.of(-1, -1., 0, 0., 1, 1.))
.add();
state1 = crac.getState("co1", curativeInstant);
state2 = crac.getState("co2", curativeInstant);
assertEquals(Set.of(ra1), crac.getRangeActions(state1, UsageMethod.AVAILABLE));
assertEquals(Set.of(ra3), crac.getRangeActions(state2, UsageMethod.AVAILABLE));
assertEquals(Set.of(ra2), crac.getRangeActions(state1, UsageMethod.FORCED));
assertEquals(Set.of(ra4), crac.getRangeActions(state2, UsageMethod.FORCED));
assertEquals(Set.of(ra1, ra2), crac.getRangeActions(state1, UsageMethod.AVAILABLE, UsageMethod.FORCED));
assertEquals(Set.of(ra3, ra4), crac.getRangeActions(state2, UsageMethod.AVAILABLE, UsageMethod.FORCED));
}
@Test
void testFilterHvdcRangeActionUsageRules() {
crac.newContingency().withId("co1").withContingencyElement("neCo", getRandomTypeContingency()).add();
crac.newContingency().withId("co2").withContingencyElement("neCo", getRandomTypeContingency()).add();
ra1 = crac.newHvdcRangeAction()
.withId("ra1")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra2 = crac.newHvdcRangeAction()
.withId("ra2")
.withNetworkElement("ne1")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra3 = crac.newHvdcRangeAction()
.withId("ra3")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
ra4 = crac.newHvdcRangeAction()
.withId("ra4")
.withNetworkElement("ne2")
.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co2").withInstant(CURATIVE_INSTANT_ID).add()
.newRange().withMin(-5).withMax(10).add()
.add();
state1 = crac.getState("co1", curativeInstant);
state2 = crac.getState("co2", curativeInstant);
assertEquals(Set.of(ra1), crac.getRangeActions(state1, UsageMethod.AVAILABLE));
assertEquals(Set.of(ra3), crac.getRangeActions(state2, UsageMethod.AVAILABLE));
assertEquals(Set.of(ra2), crac.getRangeActions(state1, UsageMethod.FORCED));
assertEquals(Set.of(ra4), crac.getRangeActions(state2, UsageMethod.FORCED));
assertEquals(Set.of(ra1, ra2), crac.getRangeActions(state1, UsageMethod.AVAILABLE, UsageMethod.FORCED));
assertEquals(Set.of(ra3, ra4), crac.getRangeActions(state2, UsageMethod.AVAILABLE, UsageMethod.FORCED));
}
@Test
void testRemoveNetworkAction() {
crac.addNetworkElement("neCo", "neCo");
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(getRandomTypeContingencyElement("neCo")));
crac.addContingency(contingency1);
NetworkActionAdder na1Adder = crac.newNetworkAction().withId("na1").withName("na1").withOperator("operator").withSpeed(10);
na1Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add();
na1Adder.newSwitchAction().withNetworkElement("ne1", "ne1").withActionType(ActionType.OPEN).add();
NetworkAction na1 = na1Adder.add();
NetworkActionAdder na2Adder = crac.newNetworkAction().withId("na2").withName("na2").withOperator("operator").withSpeed(10);
na2Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(AUTO_INSTANT_ID).add();
na2Adder.newSwitchAction().withNetworkElement("ne1", "ne1").withActionType(ActionType.OPEN).add();
NetworkAction na2 = na2Adder.add();
NetworkActionAdder na3Adder = crac.newNetworkAction().withId("na3").withName("na3").withOperator("operator").withSpeed(10);
na3Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add();
na3Adder.newSwitchAction().withNetworkElement("ne2", "ne2").withActionType(ActionType.CLOSE).add();
NetworkAction na3 = na3Adder.add();
NetworkActionAdder na4Adder = crac.newNetworkAction().withId("na4").withName("na4").withOperator("operator").withSpeed(10);
na4Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(AUTO_INSTANT_ID).add();
na4Adder.newSwitchAction().withNetworkElement("ne2", "ne2").withActionType(ActionType.CLOSE).add();
NetworkAction na4 = na4Adder.add();
state1 = crac.getState(contingency1, curativeInstant);
state2 = crac.getState(contingency1, autoInstant);
assertTrue(crac.getNetworkActions(state1, UsageMethod.FORCED).isEmpty());
assertEquals(Set.of(na1, na3), crac.getNetworkActions(state1, UsageMethod.AVAILABLE));
assertEquals(Set.of(na2, na4), crac.getNetworkActions(state2, UsageMethod.FORCED));
assertEquals(Set.of(na2, na4), crac.getNetworkActions(state2, UsageMethod.FORCED, UsageMethod.AVAILABLE));
assertEquals(4, crac.getNetworkActions().size());
assertEquals(4, crac.getRemedialActions().size());
crac.removeRemedialAction("doesnt exist 1");
crac.removeNetworkAction("doesnt exist 2");
assertEquals(4, crac.getNetworkActions().size());
crac.removeRemedialAction("na1");
assertNull(crac.getRemedialAction("na1"));
assertNotNull(crac.getNetworkElement("ne1")); // still used by na2
assertNotNull(crac.getState(contingency1, curativeInstant)); // state1, still used by na3
crac.removeNetworkAction("na2");
assertNull(crac.getNetworkAction("na2"));
assertNull(crac.getNetworkElement("ne1")); // unused
assertNotNull(crac.getState(contingency1, curativeInstant)); // state1, still used by na3
assertNotNull(crac.getState(contingency1, autoInstant)); // state2, still used by na4
crac.removeNetworkAction("na3");
assertNull(crac.getNetworkAction("na3"));
assertNotNull(crac.getNetworkElement("ne2")); // still used by na4
assertNull(crac.getState(contingency1, curativeInstant)); // unused
assertNotNull(crac.getState(contingency1, autoInstant)); // state2, still used by na4
crac.removeRemedialAction("na4");
assertEquals(0, crac.getRemedialActions().size());
assertEquals(1, crac.getNetworkElements().size());
assertNotNull(crac.getNetworkElement("neCo"));
assertEquals(0, crac.getStates().size());
}
@Test
void testFilterNetworkActionUsageRules() {
Contingency contingency1 = new Contingency("co1", "co1", Collections.singletonList(getRandomTypeContingencyElement("neCo")));
crac.addContingency(contingency1);
NetworkActionAdder na1Adder = crac.newNetworkAction().withId("na1").withName("na1").withOperator("operator").withSpeed(10);
na1Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.AVAILABLE).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add();
na1Adder.newSwitchAction().withNetworkElement("ne1", "ne1").withActionType(ActionType.OPEN).add();
NetworkAction na1 = na1Adder.add();
NetworkActionAdder na2Adder = crac.newNetworkAction().withId("na2").withName("na2").withOperator("operator").withSpeed(10);
na2Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(AUTO_INSTANT_ID).add();
na2Adder.newSwitchAction().withNetworkElement("ne1", "ne1").withActionType(ActionType.OPEN).add();
NetworkAction na2 = na2Adder.add();
NetworkActionAdder na3Adder = crac.newNetworkAction().withId("na3").withName("na3").withOperator("operator").withSpeed(10);
na3Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(CURATIVE_INSTANT_ID).add();
na3Adder.newSwitchAction().withNetworkElement("ne2", "ne2").withActionType(ActionType.CLOSE).add();
NetworkAction na3 = na3Adder.add();
NetworkActionAdder na4Adder = crac.newNetworkAction().withId("na4").withName("na4").withOperator("operator").withSpeed(10);
na4Adder.newOnContingencyStateUsageRule().withUsageMethod(UsageMethod.FORCED).withContingency("co1").withInstant(AUTO_INSTANT_ID).add();
na4Adder.newSwitchAction().withNetworkElement("ne2", "ne2").withActionType(ActionType.CLOSE).add();
NetworkAction na4 = na4Adder.add();
state1 = crac.getState(contingency1, curativeInstant);
state2 = crac.getState(contingency1, autoInstant);
assertEquals(Set.of(na1), crac.getNetworkActions(state1, UsageMethod.AVAILABLE));
assertEquals(Set.of(), crac.getNetworkActions(state2, UsageMethod.AVAILABLE));
assertEquals(Set.of(na3), crac.getNetworkActions(state1, UsageMethod.FORCED));
assertEquals(Set.of(na2, na4), crac.getNetworkActions(state2, UsageMethod.FORCED));
assertEquals(Set.of(na1, na3), crac.getNetworkActions(state1, UsageMethod.AVAILABLE, UsageMethod.FORCED));
assertEquals(Set.of(na2, na4), crac.getNetworkActions(state2, UsageMethod.AVAILABLE, UsageMethod.FORCED));
}
@Test
void testPstRangeActionAdder() {
PstRangeActionAdder pstRangeActionAdder = crac.newPstRangeAction();
assertInstanceOf(PstRangeActionAdderImpl.class, pstRangeActionAdder);
assertSame(crac, ((PstRangeActionAdderImpl) pstRangeActionAdder).getCrac());
}
@Test
void testHvdcRangeActionAdder() {
HvdcRangeActionAdder hvdcRangeActionAdder = crac.newHvdcRangeAction();
assertInstanceOf(HvdcRangeActionAdderImpl.class, hvdcRangeActionAdder);
assertSame(crac, ((HvdcRangeActionAdderImpl) hvdcRangeActionAdder).getCrac());
}
@Test
void testNetworkActionAdder() {
NetworkActionAdder networkActionAdder = crac.newNetworkAction();
assertInstanceOf(NetworkActionAdderImpl.class, networkActionAdder);
assertSame(crac, ((NetworkActionAdderImpl) networkActionAdder).getCrac());
}
@Test
void testNewInstantAlreadyDefined() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.newInstant(OUTAGE_INSTANT_ID, InstantKind.PREVENTIVE));
assertEquals("Instant 'outage' is already defined", exception.getMessage());
}
@Test
void testGetInstantNeverDefined() {
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.getInstant("never defined"));
assertEquals("Instant 'never defined' has not been defined", exception.getMessage());
}
@Test
void testGetInstantByKindWithOneInstantPerInstantKind() {
assertEquals(preventiveInstant, crac.getPreventiveInstant());
assertEquals(outageInstant, crac.getOutageInstant());
assertEquals(autoInstant, crac.getInstant(InstantKind.AUTO));
assertEquals(curativeInstant, crac.getInstant(InstantKind.CURATIVE));
}
@Test
void testGetInstants() {
assertEquals(List.of(preventiveInstant, outageInstant, autoInstant, curativeInstant), crac.getSortedInstants());
}
@Test
void testGetLastInstant() {
assertEquals(curativeInstant, crac.getLastInstant());
}
@Test
void testGetLastInstantWithMultipleInstantsPerInstantKind() {
crac.newInstant("curative 2", InstantKind.CURATIVE)
.newInstant("curative 3", InstantKind.CURATIVE);
Instant curativeInstant3 = crac.getInstant("curative 3");
assertEquals(curativeInstant3, crac.getLastInstant());
}
@Test
void testGetInstantsByKindWithTwoInstantsPerInstantKind() {
crac.newInstant("preventive 2", InstantKind.PREVENTIVE)
.newInstant("outage 2", InstantKind.OUTAGE)
.newInstant("auto 2", InstantKind.AUTO)
.newInstant("curative 2", InstantKind.CURATIVE);
Instant preventiveInstant2 = crac.getInstant("preventive 2");
Instant outageInstant2 = crac.getInstant("outage 2");
Instant autoInstant2 = crac.getInstant("auto 2");
Instant curativeInstant2 = crac.getInstant("curative 2");
assertEquals(Set.of(preventiveInstant, preventiveInstant2), crac.getInstants(InstantKind.PREVENTIVE));
assertEquals(Set.of(outageInstant, outageInstant2), crac.getInstants(InstantKind.OUTAGE));
assertEquals(Set.of(autoInstant, autoInstant2), crac.getInstants(InstantKind.AUTO));
assertEquals(Set.of(curativeInstant, curativeInstant2), crac.getInstants(InstantKind.CURATIVE));
}
@Test
void testGetInstantByKindDoesNotWorkWithTwoInstantsPerInstantKind() {
crac.newInstant("curative 2", InstantKind.CURATIVE);
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.getInstant(InstantKind.CURATIVE));
assertEquals("Crac does not contain exactly one instant of kind 'CURATIVE'. It contains 2 instants of kind 'CURATIVE'", exception.getMessage());
}
@Test
void testGetPreviousInstant() {
assertNull(crac.getInstantBefore(preventiveInstant));
assertEquals(preventiveInstant, crac.getInstantBefore(outageInstant));
assertEquals(outageInstant, crac.getInstantBefore(autoInstant));
assertEquals(autoInstant, crac.getInstantBefore(curativeInstant));
}
@Test
void testGetPreviousInstantWorksWithOtherInstance() {
Instant anotherInstanceOfInstantDefinedInTheCrac = new InstantImpl(PREVENTIVE_INSTANT_ID, InstantKind.PREVENTIVE, null);
assertNull(crac.getInstantBefore(anotherInstanceOfInstantDefinedInTheCrac));
anotherInstanceOfInstantDefinedInTheCrac = new InstantImpl(AUTO_INSTANT_ID, InstantKind.AUTO, outageInstant);
assertEquals(outageInstant, crac.getInstantBefore(anotherInstanceOfInstantDefinedInTheCrac));
}
@Test
void testGetPreviousInstantFromInvalidInstants() {
assertThrows(NullPointerException.class, () -> crac.getInstantBefore(null));
Instant instantNotDefinedInTheCrac = new InstantImpl("instantNotDefinedInTheCrac", InstantKind.PREVENTIVE, null);
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.getInstantBefore(instantNotDefinedInTheCrac));
assertEquals("Provided instant 'instantNotDefinedInTheCrac' is not defined in the CRAC", exception.getMessage());
Instant anotherInstantNotDefinedInTheCrac = new InstantImpl(OUTAGE_INSTANT_ID, InstantKind.PREVENTIVE, preventiveInstant);
exception = assertThrows(OpenRaoException.class, () -> crac.getInstantBefore(anotherInstantNotDefinedInTheCrac));
assertEquals("Provided instant {id:'outage', kind:'PREVENTIVE', order:1} is not the same {id: 'outage', kind:'OUTAGE', order:1} in the CRAC", exception.getMessage());
}
@Test
void testFirstInstantHasToBePreventive() {
CracImpl cracThatFails = new CracImpl("test-crac");
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> cracThatFails.newInstant("instant", InstantKind.AUTO));
assertEquals("The first instant in the CRAC must be preventive", exception.getMessage());
cracThatFails.newInstant("titi", InstantKind.PREVENTIVE);
exception = assertThrows(OpenRaoException.class, () -> cracThatFails.newInstant("instant", InstantKind.CURATIVE));
assertEquals("The second instant in the CRAC must be an outage", exception.getMessage());
}
@Test
void testGetUniqueInstants() {
assertEquals(preventiveInstant, crac.getPreventiveInstant());
assertEquals(outageInstant, crac.getOutageInstant());
}
@Test
void testCracHasAutoInstant() {
assertTrue(crac.hasAutoInstant());
assertFalse(new CracImpl("test-crac").hasAutoInstant());
}
@Test
void testRaUsageLimits() {
assertTrue(crac.getRaUsageLimitsPerInstant().isEmpty());
RaUsageLimits raUsageLimits1 = new RaUsageLimits();
raUsageLimits1.setMaxRa(3);
Map<Instant, RaUsageLimits> firstMap = Map.of(preventiveInstant, raUsageLimits1);
crac.newRaUsageLimits("preventive")
.withMaxRa(raUsageLimits1.getMaxRa())
.add();
assertEquals(firstMap.get(preventiveInstant), crac.getRaUsageLimitsPerInstant().get(preventiveInstant));
assertEquals(firstMap.get(preventiveInstant), crac.getRaUsageLimits(preventiveInstant));
assertEquals(firstMap, crac.getRaUsageLimitsPerInstant());
Instant fakeInstant = Mockito.mock(Instant.class);
when(fakeInstant.getId()).thenReturn("fake_instant");
OpenRaoException exception = assertThrows(OpenRaoException.class, () -> crac.newRaUsageLimits("fake_instant"));
assertEquals("The instant fake_instant does not exist in the crac.", exception.getMessage());
assertFalse(crac.getRaUsageLimitsPerInstant().containsKey(fakeInstant));
assertEquals(new RaUsageLimits(), crac.getRaUsageLimits(fakeInstant));
}
private void setUpCracWithRAs() {
Contingency contingency1 = crac.newContingency()
.withId("contingency1")
.withContingencyElement("contingency1-ne", ContingencyElementType.LINE)
.add();
Contingency contingency2 = crac.newContingency()
.withId("contingency2")
.withContingencyElement("contingency2-ne", ContingencyElementType.LINE)
.add();
crac.newFlowCnec()
.withId("cnec")
.withNetworkElement("cnec-ne")
.withContingency("contingency1")
.withInstant(CURATIVE_INSTANT_ID)
.withNominalVoltage(220.)
.newThreshold().withSide(TwoSides.TWO).withMax(1000.).withUnit(Unit.AMPERE).add()
.add();
// ra1 : preventive only
ra1 = crac.newPstRangeAction()
.withId("ra1")
.withNetworkElement("ra1-ne")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnContingencyStateUsageRule().withContingency("contingency1").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.UNDEFINED).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra2 : preventive and curative
ra2 = crac.newPstRangeAction()
.withId("ra2")
.withNetworkElement("ra2-ne")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.UNAVAILABLE).add()
.newOnContingencyStateUsageRule().withContingency("contingency2").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra3 : preventive and curative
ra3 = crac.newPstRangeAction()
.withId("ra3")
.withNetworkElement("ra3-ne")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newTapRange().withMaxTap(100).withMinTap(-100).withRangeType(RangeType.RELATIVE_TO_PREVIOUS_INSTANT).add()
.newOnContingencyStateUsageRule().withContingency("contingency1").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra4 : preventive only, but with same NetworkElement as ra5
ra4 = crac.newPstRangeAction()
.withId("ra4")
.withNetworkElement("ra4-ne1")
.withNetworkElement("ra4-ne2")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra5 : curative only, but with same NetworkElement as ra4
ra5 = crac.newPstRangeAction()
.withId("ra5")
.withNetworkElement("ra4-ne1")
.withNetworkElement("ra4-ne2")
.newOnContingencyStateUsageRule().withContingency("contingency2").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra6 : preventive and curative (onFlowConstraint)
ra6 = crac.newPstRangeAction()
.withId("ra6")
.withNetworkElement("ra6-ne")
.withOperator("FR")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnConstraintUsageRule().withCnec("cnec").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra7 : auto only
ra7 = crac.newPstRangeAction()
.withId("ra7")
.withNetworkElement("ra7-ne")
.newOnContingencyStateUsageRule().withContingency("contingency2").withInstant(AUTO_INSTANT_ID).withUsageMethod(UsageMethod.FORCED).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.withSpeed(1)
.add();
// ra8 : preventive and auto
ra8 = crac.newPstRangeAction()
.withId("ra8")
.withNetworkElement("ra8-ne")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnContingencyStateUsageRule().withContingency("contingency1").withInstant(AUTO_INSTANT_ID).withUsageMethod(UsageMethod.FORCED).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.withSpeed(2)
.add();
// ra9 : preventive only, but with same NetworkElement as ra8
ra9 = crac.newPstRangeAction()
.withId("ra9")
.withNetworkElement("ra8-ne")
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.withInitialTap(0).withTapToAngleConversionMap(Map.of(0, -100., 1, 100.))
.add();
// ra10 : preventive only, counter trade
ra10 = crac.newCounterTradeRangeAction()
.withId("ra10")
.withExportingCountry(Country.FR)
.withImportingCountry(Country.DE)
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnContingencyStateUsageRule().withContingency("contingency1").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.UNDEFINED).add()
.newRange().withMin(-1000).withMax(1000).add()
.add();
// na1 : preventive + curative
crac.newNetworkAction()
.withId("na1")
.newSwitchAction().withNetworkElement("na1-ne").withActionType(ActionType.OPEN).add()
.newOnInstantUsageRule().withInstant(PREVENTIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.newOnContingencyStateUsageRule().withContingency("contingency1").withInstant(CURATIVE_INSTANT_ID).withUsageMethod(UsageMethod.AVAILABLE).add()
.add();
state1 = crac.getState(contingency1, curativeInstant);
state2 = crac.getState(contingency2, curativeInstant);
}
@Test
void testIsRangeActionAvailableInState() {
setUpCracWithRAs();
// ra1 is available in preventive only
assertTrue(crac.isRangeActionAvailableInState(ra1, crac.getPreventiveState()));
assertFalse(crac.isRangeActionAvailableInState(ra1, state1));
assertFalse(crac.isRangeActionAvailableInState(ra1, state2));
// ra2 is available in state2 only
assertFalse(crac.isRangeActionAvailableInState(ra2, crac.getPreventiveState()));
assertFalse(crac.isRangeActionAvailableInState(ra2, state1));
assertTrue(crac.isRangeActionAvailableInState(ra2, state2));
// ra3 is available in preventive and in state1
assertTrue(crac.isRangeActionAvailableInState(ra3, crac.getPreventiveState()));
assertTrue(crac.isRangeActionAvailableInState(ra3, state1));
assertFalse(crac.isRangeActionAvailableInState(ra3, state2));
// ra4 is preventive, ra5 is available in state2, both have the same network element
assertTrue(crac.isRangeActionAvailableInState(ra4, crac.getPreventiveState()));
assertFalse(crac.isRangeActionAvailableInState(ra4, state1));
assertFalse(crac.isRangeActionAvailableInState(ra4, state2));
assertFalse(crac.isRangeActionAvailableInState(ra5, crac.getPreventiveState()));
assertFalse(crac.isRangeActionAvailableInState(ra5, state1));
assertTrue(crac.isRangeActionAvailableInState(ra5, state2));
// ra6 is available in preventive and in state1
assertTrue(crac.isRangeActionAvailableInState(ra6, crac.getPreventiveState()));
assertTrue(crac.isRangeActionAvailableInState(ra6, state1));
assertFalse(crac.isRangeActionAvailableInState(ra6, state2));
// ra10 is available in preventive only
assertTrue(crac.isRangeActionAvailableInState(ra10, crac.getPreventiveState()));
assertFalse(crac.isRangeActionAvailableInState(ra10, state1));
assertFalse(crac.isRangeActionAvailableInState(ra10, state2));
}
@Test
void testIsRangeActionPreventive() {
setUpCracWithRAs();
// ra1 is available in preventive only
assertTrue(crac.isRangeActionPreventive(ra1));
// ra2 is available in state2 only
assertFalse(crac.isRangeActionPreventive(ra2));
// ra3 is available in preventive and in state1
assertTrue(crac.isRangeActionPreventive(ra3));
// ra4 is preventive, ra5 is available in state2, both have the same network element
assertTrue(crac.isRangeActionPreventive(ra4));
assertFalse(crac.isRangeActionPreventive(ra5));
// ra6 is preventive and curative
assertTrue(crac.isRangeActionPreventive(ra6));
}
@Test
void testIsRangeActionCurative() {
setUpCracWithRAs();
// ra1 is available in preventive only
assertFalse(crac.isRangeActionAutoOrCurative(ra1));
// ra2 is available in state2 only
assertTrue(crac.isRangeActionAutoOrCurative(ra2));
// ra3 is available in preventive and in state1
assertTrue(crac.isRangeActionAutoOrCurative(ra3));
// ra4 is preventive, ra5 is available in state2, both have the same network element
assertFalse(crac.isRangeActionAutoOrCurative(ra4));
assertTrue(crac.isRangeActionAutoOrCurative(ra5));
// ra6 is preventive and curative
assertTrue(crac.isRangeActionAutoOrCurative(ra6));
}
@Test
void testIsRangeActionAuto() {
setUpCracWithRAs();
// ra7 is auto
assertTrue(crac.isRangeActionAutoOrCurative(ra7));
// ra8 is preventive and auto
assertTrue(crac.isRangeActionAutoOrCurative(ra8));
// ra9 is preventive with same network element as ra8
assertFalse(crac.isRangeActionAutoOrCurative(ra9));
}
@Test
void testGetCnecsWithPhysicalParameter() {
crac.newContingency()
.withId("co1")
.withContingencyElement("neCo", getRandomTypeContingency())
.add();
FlowCnec flowCnec = crac.newFlowCnec()
.withId("cnec")
.withNetworkElement("anyNetworkElement")
.withOperator("operator")
.withContingency("co1")
.withInstant(CURATIVE_INSTANT_ID)
.newThreshold().withMin(-1000.).withUnit(Unit.MEGAWATT).withSide(TwoSides.ONE).add()
.add();
VoltageCnec voltageCnec = crac.newVoltageCnec()
.withId("vc")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.withNetworkElement("VL1")
.withMonitored()
.newThreshold().withUnit(Unit.KILOVOLT).withMin(400.).withMax(450.).add()
.add();
AngleCnec angleCnec = crac.newAngleCnec()
.withId("acCur1")
.withInstant(CURATIVE_INSTANT_ID)
.withContingency("co1")
.withImportingNetworkElement("VL1_0")
.withExportingNetworkElement("VL2")
.withMonitored()
.newThreshold().withUnit(Unit.DEGREE).withMin(-8.).withMax(null).add()
.add();
assertEquals(Set.of(flowCnec), crac.getCnecs(PhysicalParameter.FLOW));
assertEquals(Set.of(angleCnec), crac.getCnecs(PhysicalParameter.ANGLE));
assertEquals(Set.of(voltageCnec), crac.getCnecs(PhysicalParameter.VOLTAGE));
assertEquals(Collections.emptySet(), crac.getCnecs(PhysicalParameter.FLOW, crac.getPreventiveState()));
assertEquals(Collections.emptySet(), crac.getCnecs(PhysicalParameter.ANGLE, crac.getPreventiveState()));
assertEquals(Collections.emptySet(), crac.getCnecs(PhysicalParameter.VOLTAGE, crac.getPreventiveState()));
assertEquals(Set.of(flowCnec), crac.getCnecs(PhysicalParameter.FLOW, crac.getState("co1", crac.getInstant(CURATIVE_INSTANT_ID))));
assertEquals(Set.of(angleCnec), crac.getCnecs(PhysicalParameter.ANGLE, crac.getState("co1", crac.getInstant(CURATIVE_INSTANT_ID))));
assertEquals(Set.of(voltageCnec), crac.getCnecs(PhysicalParameter.VOLTAGE, crac.getState("co1", crac.getInstant(CURATIVE_INSTANT_ID))));
}
}