From 5bcbbd5768357d4d502fd37d4221957716c7df57 Mon Sep 17 00:00:00 2001 From: Stephen Smith <56431339+StephenSmith25@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:25:11 +0100 Subject: [PATCH] update tests (#15) * update tests * add fmpy to action --- .github/workflows/main.yml | 1 + pythonfmu3/osutil.py | 4 +- .../tests/slaves/PythonSlaveWithException.py | 5 +- pythonfmu3/tests/slaves/pythonslave.py | 3 + .../tests/slaves/pythonslave_read_file.py | 5 +- pythonfmu3/tests/slaves/slavewithdep.py | 5 +- pythonfmu3/tests/test_integration.py | 88 +++++++++---------- pythonfmu3/tests/test_multiple_fmus.py | 22 ++--- 8 files changed, 71 insertions(+), 62 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f26443e..ad64121 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -107,6 +107,7 @@ jobs: pip install -r requirements.txt cd python-wheel pip install pythonfmu3*.whl + pip install fmpy pytest --pyargs pythonfmu3 cd .. shell: bash -l {0} diff --git a/pythonfmu3/osutil.py b/pythonfmu3/osutil.py index d6e70f3..568350e 100644 --- a/pythonfmu3/osutil.py +++ b/pythonfmu3/osutil.py @@ -1,5 +1,4 @@ import sys -import platform import platform @@ -8,7 +7,8 @@ def get_fmu_arch(): system = platform.system() is_x86 = platform.machine() in ["i386", "AMD64", "x86_64"] platforms = {"Windows": "windows", "Linux": "linux", "Darwin": "darwin"} - return "x86_64" if is_x86 else "x86" + "-" + platforms.get(system, "unknown") + arch = "x86_64" if is_x86 else "x86" + return arch + "-" + platforms.get(system, "unknown") def get_platform() -> str: """Get FMU binary platform folder name.""" diff --git a/pythonfmu3/tests/slaves/PythonSlaveWithException.py b/pythonfmu3/tests/slaves/PythonSlaveWithException.py index 7973175..41fd133 100644 --- a/pythonfmu3/tests/slaves/PythonSlaveWithException.py +++ b/pythonfmu3/tests/slaves/PythonSlaveWithException.py @@ -1,4 +1,4 @@ -from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Float64 +from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Float64, Fmi3Variability class PythonSlaveWithException(Fmi3Slave): @@ -8,6 +8,9 @@ def __init__(self, **kwargs): self.realIn = 22.0 self.realOut = 0.0 + self.time = 0 + + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable(Float64("realIn", causality=Fmi3Causality.input)) self.register_variable(Float64("realOut", causality=Fmi3Causality.output)) diff --git a/pythonfmu3/tests/slaves/pythonslave.py b/pythonfmu3/tests/slaves/pythonslave.py index a662dca..3696792 100644 --- a/pythonfmu3/tests/slaves/pythonslave.py +++ b/pythonfmu3/tests/slaves/pythonslave.py @@ -21,6 +21,9 @@ def __init__(self, **kwargs): self.realIn = 2. / 3. self.booleanParameter = False self.stringParameter = "dog" + self.time = 0 + + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable( Int32("intParam", causality=Fmi3Causality.parameter, variability=Fmi3Variability.tunable)) self.register_variable(Float64("realIn", causality=Fmi3Causality.input)) diff --git a/pythonfmu3/tests/slaves/pythonslave_read_file.py b/pythonfmu3/tests/slaves/pythonslave_read_file.py index d442dc3..f5afd82 100644 --- a/pythonfmu3/tests/slaves/pythonslave_read_file.py +++ b/pythonfmu3/tests/slaves/pythonslave_read_file.py @@ -1,4 +1,4 @@ -from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Fmi3Variability, String, DefaultExperiment +from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Fmi3Variability, String, DefaultExperiment, Float64 class PythonSlaveReadFile(Fmi3Slave): @@ -11,6 +11,9 @@ def __init__(self, **kwargs): with (open(f'{self.resources}/hello.txt', 'r')) as file: data = file.read() + self.time = 0 + + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable( String("file_content", getter=lambda: data, causality=Fmi3Causality.output, diff --git a/pythonfmu3/tests/slaves/slavewithdep.py b/pythonfmu3/tests/slaves/slavewithdep.py index b003be6..1b30a30 100644 --- a/pythonfmu3/tests/slaves/slavewithdep.py +++ b/pythonfmu3/tests/slaves/slavewithdep.py @@ -1,5 +1,5 @@ import math -from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Float64 +from pythonfmu3.fmi3slave import Fmi3Slave, Fmi3Causality, Float64, Fmi3Variability from localmodule import get_amplitude, get_time_constant @@ -10,6 +10,9 @@ def __init__(self, **kwargs): self.realIn = 22.0 self.realOut = 0.0 + self.time = 0 + + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable(Float64("realIn", causality=Fmi3Causality.input)) self.register_variable(Float64("realOut", causality=Fmi3Causality.output)) diff --git a/pythonfmu3/tests/test_integration.py b/pythonfmu3/tests/test_integration.py index 908d48b..01ae0fe 100644 --- a/pythonfmu3/tests/test_integration.py +++ b/pythonfmu3/tests/test_integration.py @@ -38,13 +38,12 @@ def test_integration_reset(tmp_path): md = fmpy.read_model_description(str(fmu)) unzipdir = fmpy.extract(str(fmu)) - model = fmpy.fmi3.FMI3Slave(guid=md.guid, + model = fmpy.fmi3.FMU3Slave(guid=md.guid, unzipDirectory=unzipdir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName="instance" ) model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() @@ -52,13 +51,13 @@ def test_integration_reset(tmp_path): vr = vars["realOut"].valueReference dt = 0.1 - initial_value = model.getReal([vr])[0] + initial_value = model.getFloat64([vr])[0] assert initial_value == pytest.approx(3.0, rel=1e-7) model.doStep(0.0, dt, True) - read = model.getReal([vr])[0] + read = model.getFloat64([vr])[0] assert read == pytest.approx(dt, rel=1e-7) model.reset() - read = model.getReal([vr])[0] + read = model.getFloat64([vr])[0] assert read == pytest.approx(initial_value, rel=1e-7) model.terminate() @@ -77,13 +76,12 @@ def test_integration_get_state(tmp_path): md = fmpy.read_model_description(str(fmu)) unzipdir = fmpy.extract(str(fmu)) - model = fmpy.fmi3.FMI3Slave(guid=md.guid, + model = fmpy.fmi3.FMU3Slave(guid=md.guid, unzipDirectory=unzipdir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName="instance" ) model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() @@ -98,15 +96,15 @@ def step_model(): t += dt step_model() - state = model.getFMUstate() - assert model.getReal([vr])[0] == pytest.approx(dt, rel=1e-7) + state = model.getFMUState() + assert model.getFloat64([vr])[0] == pytest.approx(dt, rel=1e-7) step_model() - assert model.getReal([vr])[0] == pytest.approx(dt * 2, rel=1e-7) - model.setFMUstate(state) - assert model.getReal([vr])[0] == pytest.approx(dt, rel=1e-7) + assert model.getFloat64([vr])[0] == pytest.approx(dt * 2, rel=1e-7) + model.setFMUState(state) + assert model.getFloat64([vr])[0] == pytest.approx(dt, rel=1e-7) step_model() - assert model.getReal([vr])[0] == pytest.approx(dt * 3, rel=1e-7) - model.freeFMUstate(state) + assert model.getFloat64([vr])[0] == pytest.approx(dt * 3, rel=1e-7) + model.freeFMUState(state) model.terminate() model.freeInstance() @@ -126,14 +124,13 @@ def test_integration_get_serialize_state(tmp_path): md = fmpy.read_model_description(fmu) unzip_dir = fmpy.extract(fmu) - model = fmpy.fmi3.FMI3Slave( + model = fmpy.fmi3.FMU3Slave( guid=md.guid, unzipDirectory=unzip_dir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName='instance1') model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() @@ -148,22 +145,22 @@ def step_model(): t += dt step_model() - state = model.getFMUstate() - assert model.getReal(vrs)[0] == pytest.approx(dt, rel=1e-7) + state = model.getFMUState() + assert model.getFloat64(vrs)[0] == pytest.approx(dt, rel=1e-7) step_model() - assert model.getReal(vrs)[0] == pytest.approx(dt * 2, rel=1e-7) - model.setFMUstate(state) - assert model.getReal(vrs)[0] == pytest.approx(dt, rel=1e-7) + assert model.getFloat64(vrs)[0] == pytest.approx(dt * 2, rel=1e-7) + model.setFMUState(state) + assert model.getFloat64(vrs)[0] == pytest.approx(dt, rel=1e-7) step_model() - assert model.getReal(vrs)[0] == pytest.approx(dt * 3, rel=1e-7) + assert model.getFloat64(vrs)[0] == pytest.approx(dt * 3, rel=1e-7) - serialize_fmu_state = model.serializeFMUstate(state) - model.freeFMUstate(state) - de_serialize_fmu_state = model.deSerializeFMUstate(serialize_fmu_state) - model.setFMUstate(de_serialize_fmu_state) - assert model.getReal(vrs)[0] == pytest.approx(dt, rel=1e-7) + serialize_fmu_state = model.serializeFMUState(state) + model.freeFMUState(state) + de_serialize_fmu_state = model.deserializeFMUState(serialize_fmu_state) + model.setFMUState(de_serialize_fmu_state) + assert model.getFloat64(vrs)[0] == pytest.approx(dt, rel=1e-7) - model.freeFMUstate(de_serialize_fmu_state) + model.freeFMUState(de_serialize_fmu_state) model.terminate() model.freeInstance() @@ -178,14 +175,13 @@ def test_integration_get(tmp_path): md = fmpy.read_model_description(fmu) unzip_dir = fmpy.extract(fmu) - model = fmpy.fmi3.FMI3Slave( + model = fmpy.fmi3.FMU3Slave( guid=md.guid, unzipDirectory=unzip_dir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName='instance1') model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() @@ -207,14 +203,14 @@ def test_integration_get(tmp_path): for key, value in to_test.items(): var = variables[key] vrs = [var.valueReference] - if var.type == "Integer": - model_value = model.getInteger(vrs)[0] - elif var.type == "Real": - model_value = model.getReal(vrs)[0] + if var.type == "Int32": + model_value = model.getInt32(vrs)[0] + elif var.type == "Float64": + model_value = model.getFloat64(vrs)[0] elif var.type == "Boolean": model_value = model.getBoolean(vrs)[0] elif var.type == "String": - model_value = model.getString(vrs)[0].decode("UTF-8") + model_value = model.getString(vrs)[0] else: pytest.xfail("Unsupported type") @@ -234,20 +230,19 @@ def test_integration_read_from_file(tmp_path): md = fmpy.read_model_description(fmu) unzip_dir = fmpy.extract(fmu) - model = fmpy.fmi3.FMI3Slave( + model = fmpy.fmi3.FMU3Slave( guid=md.guid, unzipDirectory=unzip_dir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName='instance1') model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() variables = mapped(md) var = variables["file_content"] - model_value = model.getString([var.valueReference])[0].decode("UTF-8") + model_value = model.getString([var.valueReference])[0] with (open(project_file, 'r')) as file: data = file.read() @@ -267,14 +262,13 @@ def test_integration_set(tmp_path): md = fmpy.read_model_description(fmu) unzip_dir = fmpy.extract(fmu) - model = fmpy.fmi3.FMI3Slave( + model = fmpy.fmi3.FMU3Slave( guid=md.guid, unzipDirectory=unzip_dir, modelIdentifier=md.coSimulation.modelIdentifier, instanceName='instance1') model.instantiate() - model.setupExperiment() model.enterInitializationMode() model.exitInitializationMode() @@ -292,18 +286,18 @@ def test_integration_set(tmp_path): for key, value in to_test.items(): var = variables[key] vrs = [var.valueReference] - if var.type == "Integer": - model.setInteger(vrs, [value]) - model_value = model.getInteger(vrs)[0] - elif var.type == "Real": - model.setReal(vrs, [value]) - model_value = model.getReal(vrs)[0] + if var.type == "Int32": + model.setInt32(vrs, [value]) + model_value = model.getInt32(vrs)[0] + elif var.type == "Float64": + model.setFloat64(vrs, [value]) + model_value = model.getFloat64(vrs)[0] elif var.type == "Boolean": model.setBoolean(vrs, [value]) model_value = model.getBoolean(vrs)[0] elif var.type == "String": model.setString(vrs, [value]) - model_value = model.getString(vrs)[0].decode("UTF-8") + model_value = model.getString(vrs)[0] else: pytest.xfail("Unsupported type") diff --git a/pythonfmu3/tests/test_multiple_fmus.py b/pythonfmu3/tests/test_multiple_fmus.py index 0259092..93e621c 100644 --- a/pythonfmu3/tests/test_multiple_fmus.py +++ b/pythonfmu3/tests/test_multiple_fmus.py @@ -22,7 +22,7 @@ def mapped(md): @pytest.mark.integration def test_integration_multiple_fmus(tmp_path): slave1_code = """import math -from pythonfmu3.Fmi3Slave import Fmi3Slave, Fmi3Causality, Int32, Float64, Boolean, String +from pythonfmu3 import Fmi3Slave, Fmi3Causality, Fmi3Variability, Int32, Float64, Boolean, String class Slave1(Fmi3Slave): @@ -32,6 +32,8 @@ def __init__(self, **kwargs): self.realIn = 22.0 self.realOut = 0.0 + self.time = 0 + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable(Float64("realIn", causality=Fmi3Causality.input)) self.register_variable(Float64("realOut", causality=Fmi3Causality.output)) @@ -41,7 +43,7 @@ def do_step(self, current_time, step_size): return True """ - slave2_code = """from pythonfmu3.Fmi3Slave import Fmi3Slave, Fmi3Causality, Int32, Float64, Boolean, String + slave2_code = """from pythonfmu3 import Fmi3Slave, Fmi3Causality, Fmi3Variability, Int32, Float64, Boolean, String class Slave2(Fmi3Slave): @@ -51,6 +53,8 @@ def __init__(self, **kwargs): self.realIn = 22.0 self.realOut = 0.0 + self.time = 0 + self.register_variable(Float64("time", causality=Fmi3Causality.independent, variability=Fmi3Variability.continuous)) self.register_variable(Float64("realIn", causality=Fmi3Causality.input)) self.register_variable(Float64("realOut", causality=Fmi3Causality.output)) @@ -84,21 +88,20 @@ def do_step(self, current_time, step_size): md1 = fmpy.read_model_description(fmu1) unzip_dir = fmpy.extract(fmu1) - model1 = fmpy.fmi3.FMI3Slave( + model1 = fmpy.fmi3.FMU3Slave( guid=md1.guid, unzipDirectory=unzip_dir, modelIdentifier=md1.coSimulation.modelIdentifier, instanceName='instance1') model1.instantiate() - model1.setupExperiment() model1.enterInitializationMode() model1.exitInitializationMode() md2 = fmpy.read_model_description(fmu2) unzip_dir = fmpy.extract(fmu2) - model2 = fmpy.fmi3.FMI3Slave( + model2 = fmpy.fmi3.FMU3Slave( guid=md2.guid, unzipDirectory=unzip_dir, modelIdentifier=md2.coSimulation.modelIdentifier, @@ -111,11 +114,10 @@ def do_step(self, current_time, step_size): realIn = variables2["realIn"] model2.instantiate() - model2.setupExperiment() model2.enterInitializationMode() - value = model1.getReal([realOut.valueReference])[0] - model2.setReal([realIn.valueReference], [value]) + value = model1.getFloat64([realOut.valueReference])[0] + model2.setFloat64([realIn.valueReference], [value]) model2.exitInitializationMode() @@ -125,12 +127,12 @@ def do_step(self, current_time, step_size): while time < stop_time: - model2.setReal([realIn.valueReference], [value]) + model2.setFloat64([realIn.valueReference], [value]) model1.doStep(time, step_size) model2.doStep(time, step_size) - value = model1.getReal([realOut.valueReference])[0] + value = model1.getFloat64([realOut.valueReference])[0] time += step_size