From 19b66ccca499428a3955cf0746519bcf09a867a9 Mon Sep 17 00:00:00 2001 From: David Kleiven Date: Tue, 3 Oct 2023 22:42:37 +0200 Subject: [PATCH] WIP: Refactor test suite + add support for CIM/XML import from zipped file --- src/test/AppTest.kt | 63 +++++---------------------- src/test/DataFactory.kt | 94 +++++++++++++++++++++++++++++++++++++++++ src/test/SolverTest.kt | 5 ++- 3 files changed, 108 insertions(+), 54 deletions(-) create mode 100644 src/test/DataFactory.kt diff --git a/src/test/AppTest.kt b/src/test/AppTest.kt index 761cec6..b1747f0 100644 --- a/src/test/AppTest.kt +++ b/src/test/AppTest.kt @@ -99,6 +99,16 @@ class ApplicationTest { assertContains(body, busString) } + @Test + fun `test load 14 bus network cgmes`() = + testApplication { + val response = client.submitFormWithBinaryData( + url = "/buses", + formData = formDataFromFile(ieeeCdfNetwork14CgmesFile()) + ) + assertEquals(HttpStatusCode.OK, response.status) + } + @Test fun `test default load parameters`() = testApplication { @@ -264,38 +274,9 @@ class ApplicationTest { } } -fun formDataFromFile(file: File): List { - return formData { - append( - "network", - file.readBytes(), - Headers.build { - append(HttpHeaders.ContentDisposition, "filename=${file.name}") - }, - ) - } -} -fun formDataWithEmptyNetwork(): List { - return formData { - append( - "network", - byteArrayOf(), - Headers.build { - append(HttpHeaders.ContentDisposition, "filename=emptyFile.xiidm") - } - ) - } -} -fun ieeeCdfNetwork14File(): File { - // Initialize temporary file - val file = File.createTempFile("network", ".xiidm") - file.deleteOnExit() - IeeeCdfNetworkFactory.create14().write("XIIDM", Properties(), Paths.get(file.path)) - return file -} // Function for checking some properties of a body to verify that the returned body // is a valid svg image @@ -303,28 +284,4 @@ fun isPlausibleSvg(body: String): Boolean { return body.contains(" { - return formData { - append( - "network", - minimalRawx(), - Headers.build { - append(HttpHeaders.ContentDisposition, "filename=network.rawx") - } - ) - } -} -fun minimalRawx(): ByteArray { - return ("{\"network\":{\"caseid\":{" + - "\"fields\":[\"ic\",\"sbase\",\"rev\",\"xfrrat\",\"nxfrat\",\"basfrq\",\"title1\"]," + - "\"data\":[0,100.00,35,0,0,60.00,\"PSS(R)EMinimumRAWXCase\"]}," + - "\"bus\":{\"fields\":[\"ibus\",\"name\",\"baskv\",\"ide\"]," + - "\"data\":[[1,\"Slack-Bus\",138.0,3],[2,\"Load-Bus\",138.01]]}," + - "\"load\":{\"fields\":[\"ibus\",\"loadid\",\"stat\",\"pl\",\"ql\"]," + - "\"data\":[[2,\"1\",1,40.0,15.0]]}," + - "\"generator\":{\"fields\":[\"ibus\",\"machid\",\"pg\",\"qg\"]," + - "\"data\":[[1,\"1\",\"40.35\",\"10.87\"]]}," + - "\"acline\":{\"fields\":[\"ibus\",\"jbus\",\"ckt\",\"rpu\",\"xpu\",\"bpu\"]," + - "\"data\":[[1,2,\"1\",0.01938,0.05917,0.05280]]}}}").toByteArray() -} diff --git a/src/test/DataFactory.kt b/src/test/DataFactory.kt new file mode 100644 index 0000000..1ddab9e --- /dev/null +++ b/src/test/DataFactory.kt @@ -0,0 +1,94 @@ +import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory +import io.ktor.client.request.forms.* +import io.ktor.http.* +import io.ktor.http.content.* +import java.io.File +import java.io.FileOutputStream +import java.nio.file.Paths +import java.util.* +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream + +fun ieeeCdfNetwork14CgmesFile(): File { + val file = File.createTempFile("network_cgmes", ".zip") + file.deleteOnExit() + + IeeeCdfNetworkFactory.create14().write("CGMES", null, Paths.get(file.path.replace(".zip", ""))) + + // Read the produced files in EQ/SSH/SV/TP and create one zip archive + val withOutExtension = file.path.toString().replace(".zip", "") + val cimXmlFiles = listOf("EQ", "TP", "SV", "SSH").map { profile -> "${withOutExtension}_${profile}.xml"} + + val fileOutputStream = FileOutputStream(file) + val zipOutputStream = ZipOutputStream(fileOutputStream) + for (cimXmlFile in cimXmlFiles) { + val zipEntry = ZipEntry(cimXmlFile) // TODO: Fix zip entry should not contain full path + zipOutputStream.putNextEntry(zipEntry) + val cimFile = File(cimXmlFile) + val bytes = cimFile.readBytes() + zipOutputStream.write(bytes, 0, bytes.size) + zipOutputStream.closeEntry() + cimFile.delete() + } + zipOutputStream.close() + return file +} + +fun formDataMinimalNetworkRawx(): List { + return formData { + append( + "network", + minimalRawx(), + Headers.build { + append(HttpHeaders.ContentDisposition, "filename=network.rawx") + } + ) + } +} + +fun ieeeCdfNetwork14File(): File { + // Initialize temporary file + val file = File.createTempFile("network", ".xiidm") + file.deleteOnExit() + + IeeeCdfNetworkFactory.create14().write("XIIDM", Properties(), Paths.get(file.path)) + return file +} + +fun minimalRawx(): ByteArray { + return ("{\"network\":{\"caseid\":{" + + "\"fields\":[\"ic\",\"sbase\",\"rev\",\"xfrrat\",\"nxfrat\",\"basfrq\",\"title1\"]," + + "\"data\":[0,100.00,35,0,0,60.00,\"PSS(R)EMinimumRAWXCase\"]}," + + "\"bus\":{\"fields\":[\"ibus\",\"name\",\"baskv\",\"ide\"]," + + "\"data\":[[1,\"Slack-Bus\",138.0,3],[2,\"Load-Bus\",138.01]]}," + + "\"load\":{\"fields\":[\"ibus\",\"loadid\",\"stat\",\"pl\",\"ql\"]," + + "\"data\":[[2,\"1\",1,40.0,15.0]]}," + + "\"generator\":{\"fields\":[\"ibus\",\"machid\",\"pg\",\"qg\"]," + + "\"data\":[[1,\"1\",\"40.35\",\"10.87\"]]}," + + "\"acline\":{\"fields\":[\"ibus\",\"jbus\",\"ckt\",\"rpu\",\"xpu\",\"bpu\"]," + + "\"data\":[[1,2,\"1\",0.01938,0.05917,0.05280]]}}}").toByteArray() +} + +fun formDataWithEmptyNetwork(): List { + return formData { + append( + "network", + byteArrayOf(), + Headers.build { + append(HttpHeaders.ContentDisposition, "filename=emptyFile.xiidm") + } + ) + } +} + +fun formDataFromFile(file: File): List { + return formData { + append( + "network", + file.readBytes(), + Headers.build { + append(HttpHeaders.ContentDisposition, "filename=${file.name}") + }, + ) + } +} \ No newline at end of file diff --git a/src/test/SolverTest.kt b/src/test/SolverTest.kt index 4124b22..ae5b59d 100644 --- a/src/test/SolverTest.kt +++ b/src/test/SolverTest.kt @@ -1,8 +1,12 @@ import com.github.statnett.loadflowservice.defaultLoadFlowParameters +import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory import com.powsybl.loadflow.LoadFlowParameters import com.powsybl.loadflow.json.JsonLoadFlowParameters import org.junit.Test import java.io.ByteArrayInputStream +import java.io.File +import java.nio.file.Paths +import java.util.* import kotlin.test.assertEquals class SolverTest { @@ -13,5 +17,4 @@ class SolverTest { val fromJson = JsonLoadFlowParameters.read(ByteArrayInputStream(defaultJson.toByteArray())) assertEquals(parameters.toString(), fromJson.toString()) } - } \ No newline at end of file