GroovyScriptPostProcessorTest.java
/**
* Copyright (c) 2017, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.iidm.network.scripting;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.commons.config.InMemoryPlatformConfig;
import com.powsybl.commons.config.MapModuleConfig;
import com.powsybl.commons.config.PlatformConfig;
import com.powsybl.computation.AbstractTaskInterruptionTest;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.ReactiveCapabilityCurve;
import com.powsybl.iidm.network.extensions.GeneratorEntsoeCategory;
import com.powsybl.iidm.network.extensions.LoadDetail;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Mathieu Bague {@literal <mathieu.bague at rte-france.com>}
*/
class GroovyScriptPostProcessorTest extends AbstractTaskInterruptionTest {
private FileSystem fileSystem;
@BeforeEach
void setUp() throws IOException {
fileSystem = Jimfs.newFileSystem(Configuration.unix());
}
@AfterEach
void tearDown() throws IOException {
fileSystem.close();
}
@Test
void test() throws IOException {
InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem);
Path script = platformConfig.getConfigDir().map(p -> p.resolve(GroovyScriptPostProcessor.DEFAULT_SCRIPT_NAME)).orElse(null);
assertNotNull(script);
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/import-post-processor.groovy")), script);
test(platformConfig);
// Test with a custom script name
script = platformConfig.getConfigDir().map(p -> p.resolve("custom-script.groovy")).orElse(null);
assertNotNull(script);
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/import-post-processor.groovy")), script);
MapModuleConfig moduleConfig = platformConfig.createModuleConfig("groovy-post-processor");
moduleConfig.setStringProperty("script", script.toAbsolutePath().toString());
test(platformConfig);
}
@Test
void testEurostagFactory() throws IOException {
// Create configuration
InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem);
// Copy script
Path script = platformConfig.getConfigDir().map(p -> p.resolve(GroovyScriptPostProcessor.DEFAULT_SCRIPT_NAME)).orElse(null);
assertNotNull(script);
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/script-eurostag.groovy")), script);
// Create post-processor
GroovyScriptPostProcessor processor = new GroovyScriptPostProcessor(platformConfig);
// Create network
Network network = EurostagTutorialExample1Factory.create();
assertEquals(2, network.getVoltageLevelStream().filter(vl -> vl.getNominalV() > 300).count());
network.getGenerator("GEN").getTerminal().disconnect();
try { // Launch process
processor.process(network, LocalComputationManager.getDefault());
} catch (Exception e) {
throw new RuntimeException(e);
}
// Check processing results
assertEquals(1, network.getVoltageLevelStream().filter(vl -> vl.getNominalV() > 300).count());
assertEquals(280, network.getVoltageLevel("VLHV1").getNominalV(), 0.0);
assertNotNull(network.getLoad("LOAD").getExtension(LoadDetail.class));
assertEquals(100, network.getLoad("LOAD").getExtension(LoadDetail.class).getVariableActivePower(), 0.0);
assertEquals(500, network.getLoad("LOAD").getExtension(LoadDetail.class).getFixedActivePower(), 0.0);
assertNotNull(network.getGenerator("GEN").getExtension(GeneratorEntsoeCategory.class));
assertEquals(4, network.getGenerator("GEN").getExtension(GeneratorEntsoeCategory.class).getCode());
assertEquals(0, network.getBusView().getBus("VLLOAD_0").getAngle(), 0.0);
assertTrue(network.getGenerator("GEN").getTerminal().isConnected());
}
@Test
void testFourSubstationsFactory() throws IOException {
// Create configuration
InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem);
// Copy script
Path script = platformConfig.getConfigDir().map(p -> p.resolve(GroovyScriptPostProcessor.DEFAULT_SCRIPT_NAME)).orElse(null);
assertNotNull(script);
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/script-four-substations.groovy")), script);
// Create post-processor
GroovyScriptPostProcessor processor = new GroovyScriptPostProcessor(platformConfig);
// Create network
Network network = FourSubstationsNodeBreakerFactory.create();
try { // Launch process
processor.process(network, LocalComputationManager.getDefault());
} catch (Exception e) {
throw new RuntimeException(e);
}
// Check processing results
assertEquals(800, network.getGenerator("GEN2").getTargetP(), 0.0);
for (ReactiveCapabilityCurve.Point point : network.getGenerator("GEN2").getReactiveLimits(ReactiveCapabilityCurve.class).getPoints()) {
if (point.getP() == 200) {
assertEquals(-350, point.getMinQ(), 0.0);
assertEquals(350, point.getMaxQ(), 0.0);
}
if (point.getP() == 800) {
assertEquals(-400, point.getMinQ(), 0.0);
assertEquals(400, point.getMaxQ(), 0.0);
}
}
assertTrue(network.getGenerator("GEN2").getTerminal().isConnected());
}
private void test(PlatformConfig platformConfig) {
GroovyScriptPostProcessor processor = new GroovyScriptPostProcessor(platformConfig);
assertEquals("groovyScript", processor.getName());
try {
processor.process(null, null);
fail();
} catch (Exception ignored) {
}
}
@ParameterizedTest
@Timeout(10)
@ValueSource(booleans = {false, true})
void testTaskInterruption(boolean isDelayed) throws Exception {
// Create configuration
InMemoryPlatformConfig platformConfig = new InMemoryPlatformConfig(fileSystem);
// Copy script
Path script = platformConfig.getConfigDir().map(p -> p.resolve(GroovyScriptPostProcessor.DEFAULT_SCRIPT_NAME)).orElse(null);
assertNotNull(script);
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/script-four-substations.groovy")), script);
// Create post-processor
GroovyScriptPostProcessor processor = new GroovyScriptPostProcessor(platformConfig);
// Create network
Network network = FourSubstationsNodeBreakerFactory.create();
testCancelShortTask(isDelayed, () -> {
try {
processor.process(network, LocalComputationManager.getDefault());
return 0;
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}