SweCneTest.java
/*
* Copyright (c) 2022, 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.raoresult.io.cne.swe;
import com.powsybl.iidm.network.Network;
import com.powsybl.openrao.commons.PhysicalParameter;
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.InstantKind;
import com.powsybl.openrao.data.crac.api.cnec.Cnec;
import com.powsybl.openrao.data.crac.api.parameters.CracCreationParameters;
import com.powsybl.openrao.data.crac.impl.AngleCnecValue;
import com.powsybl.openrao.data.crac.io.cim.parameters.CimCracCreationParameters;
import com.powsybl.openrao.data.crac.io.cim.parameters.RangeActionSpeed;
import com.powsybl.openrao.data.raoresult.api.RaoResult;
import com.powsybl.openrao.monitoring.results.CnecResult;
import com.powsybl.openrao.monitoring.results.MonitoringResult;
import com.powsybl.openrao.monitoring.results.RaoResultWithAngleMonitoring;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.w3c.dom.Node;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.builder.Input;
import org.xmlunit.diff.DefaultComparisonFormatter;
import org.xmlunit.diff.Diff;
import org.xmlunit.diff.Difference;
import java.io.*;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Philippe Edwards {@literal <philippe.edwards at rte-france.com>}
*/
class SweCneTest {
private Crac crac;
private CracCreationContext cracCreationContext;
private Network network;
private RaoResultWithAngleMonitoring raoResultWithAngle;
private RaoResultWithAngleMonitoring raoResultFailureWithAngle;
private Properties properties;
@BeforeEach
public void setUp() throws IOException {
network = Network.read(new File(SweCneTest.class.getResource("/TestCase16NodesWith2Hvdc.xiidm").getFile()).toString());
InputStream is = getClass().getResourceAsStream("/CIM_CRAC.xml");
Set<RangeActionSpeed> rangeActionSpeeds = Set.of(new RangeActionSpeed("BBE2AA11 FFR3AA11 1", 1), new RangeActionSpeed("BBE2AA12 FFR3AA12 1", 2), new RangeActionSpeed("PRA_1", 3));
CimCracCreationParameters cimCracCreationParameters = new CimCracCreationParameters();
cimCracCreationParameters.setRemedialActionSpeed(rangeActionSpeeds);
CracCreationParameters cracCreationParameters = new CracCreationParameters();
cracCreationParameters.setCracFactoryName("CracImplFactory");
cracCreationParameters.addExtension(CimCracCreationParameters.class, cimCracCreationParameters);
cracCreationParameters.getExtension(CimCracCreationParameters.class).setTimestamp(OffsetDateTime.of(2021, 4, 2, 12, 30, 0, 0, ZoneOffset.UTC));
cracCreationContext = Crac.readWithContext("CIM_CRAC.xml", is, network, cracCreationParameters);
crac = cracCreationContext.getCrac();
InputStream inputStream = null;
try {
inputStream = new FileInputStream(SweCneTest.class.getResource("/RaoResult.json").getFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
RaoResult raoResult = RaoResult.read(inputStream, crac);
InputStream inputStream3 = null;
try {
inputStream3 = new FileInputStream(SweCneTest.class.getResource("/RaoResultWithFailure.json").getFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
RaoResult raoResultWithFailure = RaoResult.read(inputStream3, crac);
MonitoringResult monitoringResult = new MonitoringResult(PhysicalParameter.ANGLE,
Set.of(new CnecResult(crac.getCnec("ac1"), Unit.DEGREE, new AngleCnecValue(4.0), 2., Cnec.SecurityStatus.SECURE)),
Map.of(crac.getState("Co-1", crac.getInstant(InstantKind.CURATIVE)), Set.of(crac.getRemedialAction("na1"))),
Cnec.SecurityStatus.SECURE);
raoResultWithAngle = new RaoResultWithAngleMonitoring(raoResult, monitoringResult);
raoResultFailureWithAngle = new RaoResultWithAngleMonitoring(raoResultWithFailure, monitoringResult);
properties = new Properties();
properties.setProperty("rao-result.export.swe-cne.document-id", "documentId");
properties.setProperty("rao-result.export.swe-cne.revision-number", "1");
properties.setProperty("rao-result.export.swe-cne.domain-id", "domainId");
properties.setProperty("rao-result.export.swe-cne.process-type", "Z01");
properties.setProperty("rao-result.export.swe-cne.sender-id", "senderId");
properties.setProperty("rao-result.export.swe-cne.sender-role", "A04");
properties.setProperty("rao-result.export.swe-cne.receiver-id", "receiverId");
properties.setProperty("rao-result.export.swe-cne.receiver-role", "A36");
properties.setProperty("rao-result.export.swe-cne.time-interval", "2021-04-02T12:00:00Z/2021-04-02T13:00:00Z");
}
@Test
void testExport() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
new SweCneExporter().exportData(raoResultWithAngle, cracCreationContext, properties, outputStream);
try {
InputStream inputStream = new FileInputStream(SweCneTest.class.getResource("/SweCNE_Z01.xml").getFile());
compareCneFiles(inputStream, new ByteArrayInputStream(outputStream.toByteArray()));
} catch (IOException e) {
Assertions.fail();
}
}
@Test
void testExportWithFailure() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
new SweCneExporter().exportData(raoResultFailureWithAngle, cracCreationContext, properties, outputStream);
try {
InputStream inputStream = new FileInputStream(SweCneTest.class.getResource("/SweCNEWithFailure_Z01.xml").getFile());
compareCneFiles(inputStream, new ByteArrayInputStream(outputStream.toByteArray()));
} catch (IOException e) {
Assertions.fail();
}
}
@Test
void testValidateSchemaOk() {
try {
InputStream inputStream = new FileInputStream(SweCneTest.class.getResource("/SweCNE.xml").getFile());
assertTrue(SweCneExporter.validateCNESchema(new String(inputStream.readAllBytes())));
} catch (IOException e) {
Assertions.fail();
}
}
@Test
void testValidateSchemaNok() {
try {
InputStream inputStream = new FileInputStream(SweCneTest.class.getResource("/SweCNE_wrong.xml").getFile());
assertFalse(SweCneExporter.validateCNESchema(new String(inputStream.readAllBytes())));
} catch (IOException e) {
Assertions.fail();
}
}
public static void compareCneFiles(InputStream expectedCneInputStream, InputStream actualCneInputStream) throws AssertionError {
DiffBuilder db = DiffBuilder
.compare(Input.fromStream(expectedCneInputStream))
.withTest(Input.fromStream(actualCneInputStream))
.ignoreComments()
.withNodeFilter(SweCneTest::shouldCompareNode);
Diff d = db.build();
if (d.hasDifferences()) {
DefaultComparisonFormatter formatter = new DefaultComparisonFormatter();
StringBuffer buffer = new StringBuffer();
for (Difference ds : d.getDifferences()) {
buffer.append(formatter.getDescription(ds.getComparison()) + "\n");
}
throw new AssertionError("There are XML differences in CNE files\n" + buffer);
}
assertFalse(d.hasDifferences());
}
private static boolean shouldCompareNode(Node node) {
if (node.getNodeName().equals("mRID")) {
// For the following fields, mRID is generated randomly as per the CNE specifications
// We should not compare them with the test file
return !node.getParentNode().getNodeName().equals("TimeSeries")
&& !node.getParentNode().getNodeName().equals("Constraint_Series");
} else {
return !(node.getNodeName().equals("createdDateTime"));
}
}
}