Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests #66

Merged
merged 53 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
5f65962
Add devcontainer and Dependencies
halentin May 28, 2024
33a91bc
template for FMI2/3 tests
ThummeTo May 31, 2024
1d938fd
s
halentin May 31, 2024
678ca14
Merge branch 'tests2' into tests
halentin May 31, 2024
29122e1
Unzip and Load
halentin May 31, 2024
0ce617b
switch container to 22.04
halentin May 31, 2024
b05f4bf
add os and architecture distinction and check
halentin May 31, 2024
84439e3
add passing test to os change
halentin May 31, 2024
007b340
Working Tests for Instantiate, Free, GetVersion and GetTypesPlatform
halentin Jun 4, 2024
0ebc1d5
create utils.jl
halentin Jun 5, 2024
e0f2852
os check in utils
halentin Jun 5, 2024
f270aaf
Get/SetStatus Tests, type checking
halentin Jun 5, 2024
7861259
typo
halentin Jun 5, 2024
4e6b259
SetDebugLogging
halentin Jun 5, 2024
4682b90
Reset + Terminate
halentin Jun 5, 2024
f41cab2
FreeState
halentin Jun 5, 2024
5c047fe
serializedsize
halentin Jun 5, 2024
3c94fce
typo
halentin Jun 6, 2024
95af3a1
Getter and Setter
halentin Jun 6, 2024
65cdff1
get/set and directionalderivative
halentin Jun 6, 2024
a4cfbd1
ME-specific Functions
halentin Jun 7, 2024
cfba806
move type check to utils
halentin Jun 7, 2024
e5df48d
Testsets
halentin Jun 7, 2024
ac3330b
some CS Tests
halentin Jun 7, 2024
af3f925
logging?
halentin Jun 10, 2024
acc1e90
ähh
halentin Jun 10, 2024
6edc1b7
working generic and ME-specific functions
halentin Jun 10, 2024
00090d3
remove component typecast
halentin Jun 10, 2024
778127a
try internal callback
halentin Jun 10, 2024
353a20e
fix terminate test with logger
halentin Jun 12, 2024
47e0e3c
add os distinction to cblibpath
halentin Jun 12, 2024
6064af1
add binaries for linux and mac
halentin Jun 12, 2024
45d2e71
add function to create callbacks
halentin Jun 12, 2024
6e4dbfd
stop logging
halentin Jun 12, 2024
3d454e3
CS Get/Set Tests
halentin Jun 13, 2024
58023c3
Get and Set Real Input and Output Derivatives CS
halentin Jun 13, 2024
72f7443
split files
halentin Jun 13, 2024
0b51fbf
remove todo
halentin Jun 13, 2024
a98e01f
remove devcontainer
halentin Jun 13, 2024
ed54c2a
add download for callbacks
halentin Jun 13, 2024
0b9bd0f
fix download dll on windows
halentin Jun 13, 2024
c9a7bbd
replace OS-Check Test with warning and skip
halentin Jun 17, 2024
04726b4
add begin and end to testsets for 1.6 compatibility
halentin Jun 17, 2024
b04f824
remove Type Checks and "fix" 32 Bit Tests
halentin Jun 18, 2024
0683f94
Add Testing with IO FMU and Tests for fmi2String and fmi2Boolean
halentin Jun 20, 2024
d4c09dc
move CS Get/Set OutputDerivatives to IO-FMU
halentin Jun 20, 2024
0361bc1
Supress expected Warnings and CVODE Stats
halentin Jun 20, 2024
a967276
point to right 32 bit binaries
halentin Jun 20, 2024
23dbff5
remove unnecessary DoStep that Errors on 32 Bit for some reason
halentin Jun 20, 2024
fe7822b
decrease dostep size
halentin Jun 20, 2024
c5f981c
change stepsize back
halentin Jun 20, 2024
d43cb4a
only Test DoStep on x64
halentin Jun 20, 2024
dea4428
Merge branch 'main' into tests
ThummeTo Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "FMICore"
uuid = "8af89139-c281-408e-bce2-3005eb87462f"
authors = ["TT <tobias.thummerer@informatik.uni-augsburg.de>", "LM <lars.mikelsons@informatik.uni-augsburg.de>", "JK <josef.kircher@student.uni-augsburg.de>"]
version = "1.0.1"
version = "1.0.2"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
12 changes: 6 additions & 6 deletions src/FMI2/cfunc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ Source: FMISpec2.0.2[p.22]: 2.1.5 Creation, Destruction and Logging of FMU Insta

The function controls debug logging that is output via the logger function callback. If loggingOn = fmi2True, debug logging is enabled, otherwise it is switched off.
"""
function fmi2SetDebugLogging(cfunc::Ptr{Cvoid}, c::fmi2Component, logginOn::fmi2Boolean, nCategories::Csize_t, categories::Union{Ptr{fmi2String}, AbstractArray{fmi2String}})
function fmi2SetDebugLogging(cfunc::Ptr{Cvoid}, c::fmi2Component, loggingOn::fmi2Boolean, nCategories::Csize_t, categories::Union{Ptr{fmi2String}, AbstractArray{fmi2String}})
status = ccall(cfunc,
fmi2Status,
(fmi2Component, fmi2Boolean, Csize_t, Ptr{fmi2String}),
c, logginOn, nCategories, categories)
@debug "fmi2SetDebugLogging(c: $(c), logginOn: $(loggingOn), nCategories: $(nCategories), categories: $(categories)) → $(status)"
c, loggingOn, nCategories, categories)
@debug "fmi2SetDebugLogging(c: $(c), loggingOn: $(loggingOn), nCategories: $(nCategories), categories: $(categories)) → $(status)"
return status
end
export fmi2SetDebugLogging
Expand Down Expand Up @@ -350,12 +350,12 @@ Source: FMISpec2.0.2[p.26]: 2.1.8 Getting and Setting the Complete FMU State

fmi2SerializeFMUstate serializes the data which is referenced by pointer FMUstate and copies this data in to the byte vector serializedState of length size
"""
function fmi2SerializeFMUstate!(cfunc::Ptr{Cvoid}, c::fmi2Component, FMUstate::fmi2FMUstate, serialzedState::AbstractArray{fmi2Byte}, size::Csize_t)
function fmi2SerializeFMUstate!(cfunc::Ptr{Cvoid}, c::fmi2Component, FMUstate::fmi2FMUstate, serializedState::AbstractArray{fmi2Byte}, size::Csize_t)
status = ccall(cfunc,
fmi2Status,
(fmi2Component, fmi2FMUstate, Ptr{fmi2Byte}, Csize_t),
c, FMUstate, serialzedState, size)
@debug "fmi2SerializeFMUstate(c: $(c), FMUstate: $(FMUstate), serialzedState: $(serializedState), size: $(size)) → $(status)"
c, FMUstate, serializedState, size)
@debug "fmi2SerializeFMUstate(c: $(c), FMUstate: $(FMUstate), serializedState: $(serializedState), size: $(size)) → $(status)"
return status
end
export fmi2SerializeFMUstate!
Expand Down
57 changes: 57 additions & 0 deletions test/FMI2/CS.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using Libdl

function test_CS(lib, cblibpath)
component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_cs"), fmi2TypeCoSimulation, pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))

@test fmi2StatusOK == fmi2SetupExperiment(dlsym(lib, :fmi2SetupExperiment),component, fmi2Boolean(false), fmi2Real(0.0), fmi2Real(0.0), fmi2Boolean(false), fmi2Real(1.0))


fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)
@test fmi2StatusOK == fmi2DoStep(dlsym(lib, :fmi2DoStep), component, fmi2Real(0.0), fmi2Real(0.1), fmi2False)

status = fmi2Status(fmi2StatusOK)
statusptr = pointer([status])
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetStatus!(dlsym(lib, :fmi2GetStatus), component, fmi2StatusKindDoStepStatus, Ptr{fmi2Status}(statusptr))


status = fmi2Real(0.0)
statusptr = pointer([status])
@test fmi2StatusOK == fmi2GetRealStatus!(dlsym(lib, :fmi2GetRealStatus), component, fmi2StatusKindLastSuccessfulTime, Ptr{fmi2Real}(statusptr))

status = fmi2Integer(0)
statusptr = pointer([status])
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetIntegerStatus!(dlsym(lib, :fmi2GetIntegerStatus), component, Cuint(2), Ptr{fmi2Integer}(statusptr))

status = fmi2Boolean(false)
statusptr = pointer([status])
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetBooleanStatus!(dlsym(lib, :fmi2GetBooleanStatus), component, Cuint(2), Ptr{fmi2Boolean}(statusptr))

status = "test"
statusptr = pointer(status)
# Async is not supported in this FMU, so the status should be fmi2StatusDiscard
@test fmi2StatusDiscard == fmi2GetStringStatus!(dlsym(lib, :fmi2GetStringStatus), component, Cuint(2), Ptr{fmi2String}(statusptr))


fmireference = [fmi2ValueReference(16777220)]
status = fmi2SetRealInputDerivatives(dlsym(lib, :fmi2SetRealInputDerivatives), component, fmireference, Csize_t(1), [fmi2Integer(1)], fmi2Real.([1.0]))
# this should warn because the FMU does not have any inputs
@test status == fmi2StatusWarning

fmireference = [fmi2ValueReference(16777220)]
values = zeros(fmi2Real, 1)
status = fmi2GetRealOutputDerivatives!(dlsym(lib, :fmi2GetRealOutputDerivatives), component, fmireference, Csize_t(1), [fmi2Integer(1)], values)
# this should warn because the FMU does not have any outputs
@test status == fmi2StatusWarning


fmi2Terminate(dlsym(lib, :fmi2Terminate), component)

end
56 changes: 56 additions & 0 deletions test/FMI2/ME.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using Libdl

function test_ME(lib, cblibpath)
component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_me"), fmi2TypeModelExchange, pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))
@test component != C_NULL

fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)
fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)

@test fmi2StatusOK == fmi2EnterEventMode(dlsym(lib, :fmi2Instantiate), component)

eventInfo = fmi2EventInfo()
ptr = Ptr{fmi2EventInfo}(pointer_from_objref(eventInfo))

@test fmi2StatusOK == fmi2NewDiscreteStates!(dlsym(lib, :fmi2NewDiscreteStates), component, ptr)

@test fmi2StatusOK == fmi2EnterContinuousTimeMode(dlsym(lib, :fmi2EnterContinuousTimeMode), component)

enterEventMode = fmi2Boolean(false)
terminateSimulation = fmi2Boolean(false)
@test fmi2StatusOK == fmi2CompletedIntegratorStep!(dlsym(lib, :fmi2CompletedIntegratorStep), component, fmi2Boolean(false), pointer([enterEventMode]), pointer([terminateSimulation]))

@test fmi2StatusOK == fmi2SetTime(dlsym(lib, :fmi2SetTime), component, fmi2Real(0.0))

n_states = Csize_t(2)
state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetContinuousStates!(dlsym(lib, :fmi2GetContinuousStates), component,state_arr, n_states)

state_arr[2] = 2.0
@test fmi2StatusOK == fmi2SetContinuousStates(dlsym(lib, :fmi2SetContinuousStates), component,state_arr, n_states)

state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetContinuousStates!(dlsym(lib, :fmi2GetContinuousStates), component,state_arr, n_states)
@test state_arr[2] == 2.0

n_indicators = Csize_t(2)
indicator_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetEventIndicators!(dlsym(lib, :fmi2GetEventIndicators), component,indicator_arr, n_indicators)

nom_state_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetNominalsOfContinuousStates!(dlsym(lib, :fmi2GetNominalsOfContinuousStates), component, nom_state_arr, n_states)

der_arr = zeros(fmi2Real, 2)
@test fmi2StatusOK == fmi2GetDerivatives!(dlsym(lib, :fmi2GetDerivatives), component,der_arr, n_states)
# Acceleration should be equal to Gravity in this FMU
if Sys.WORD_SIZE == 64
# on 32 Bit this returns 9.81 * 10^16 which is not equal to -9.81
@test der_arr[2] ≈ -9.81
end

@test fmi2StatusOK == fmi2Terminate(dlsym(lib, :fmi2Terminate), component)
end
21 changes: 21 additions & 0 deletions test/FMI2/cfunc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using Libdl

include.(["utils.jl", "ME.jl", "CS.jl", "generic.jl"])


binarypath, fmu_path, cblibpath = get_os_binaries()
if binarypath != ""
lib = dlopen(binarypath)
# Missing Tests for fmi2<Set, Get><Boolean, String> because the FMU we are testing with doesnt variables of these types
@testset "Generic Functions in ME Mode" begin test_generic(lib,cblibpath, fmi2TypeModelExchange) end
@testset "Generic Functions in CS Mode" begin test_generic(lib,cblibpath, fmi2TypeCoSimulation) end
@testset "ME-specific Functions" begin test_ME(lib, cblibpath) end
@testset "CS-specific Functions" begin test_CS(lib, cblibpath) end
else
@warn "No valid FMU binaries found for this OS. Skipping tests."
end
101 changes: 101 additions & 0 deletions test/FMI2/generic.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Copyright (c) 2021 Tobias Thummerer, Lars Mikelsons, Josef Kircher
# Licensed under the MIT license. See LICENSE file in the project root for details.
#

using Libdl

function test_generic(lib, cblibpath, type::fmi2Type)
# Tests missing for fmi2<Set, Get><Boolean, String> because the FMU we are testing with doesnt have such variables

cGetTypesPlatform = dlsym(lib, :fmi2GetTypesPlatform)
test = fmi2GetTypesPlatform(cGetTypesPlatform)
@test unsafe_string(test) == "default"

## fmi2GetVersion TODO get Version from modelDescription.xml
vers = fmi2GetVersion(dlsym(lib, :fmi2GetVersion))
@test unsafe_string(vers) == "2.0"

# fmi2Instantiate

component = fmi2Instantiate(dlsym(lib, :fmi2Instantiate), pointer("test_generic"), type, pointer("{3c564ab6-a92a-48ca-ae7d-591f819b1d93}"), pointer("file:///"), Ptr{fmi2CallbackFunctions}(pointer_from_objref(get_callbacks(cblibpath))), fmi2Boolean(false), fmi2Boolean(false))
@test component != C_NULL

@test fmi2StatusOK == fmi2SetDebugLogging(dlsym(lib, :fmi2SetDebugLogging), component, fmi2False, Unsigned(0), AbstractArray{fmi2String}([]))
@test fmi2StatusOK == fmi2SetDebugLogging(dlsym(lib, :fmi2SetDebugLogging), component, fmi2True, Unsigned(0), AbstractArray{fmi2String}([]))

# fmi2SetupExperiment

@test fmi2StatusOK == fmi2SetupExperiment(dlsym(lib, :fmi2SetupExperiment),component, fmi2Boolean(false), fmi2Real(0.0), fmi2Real(0.0), fmi2Boolean(false), fmi2Real(1.0))



# get, set and free State
state = fmi2FMUstate()
stateRef = Ref(state)

@test fmi2StatusOK == fmi2GetFMUstate!(dlsym(lib, :fmi2GetFMUstate), component, stateRef)
state = stateRef[]

@test typeof(state) == fmi2FMUstate

@test fmi2StatusOK == fmi2SetFMUstate(dlsym(lib, :fmi2SetFMUstate), component, state)
stateRef = Ref(state)

size_ptr = Ref{Csize_t}(0)
@test fmi2StatusOK == fmi2SerializedFMUstateSize!(dlsym(lib, :fmi2SerializedFMUstateSize), component, state, size_ptr)
size = size_ptr[]

serializedState = Array{fmi2Byte}(zeros(size))
@test fmi2StatusOK == fmi2SerializeFMUstate!(dlsym(lib,:fmi2SerializeFMUstate), component, state, serializedState, size)

@test fmi2StatusOK == fmi2DeSerializeFMUstate!(dlsym(lib, :fmi2DeSerializeFMUstate), component, serializedState, size, stateRef)

@test stateRef[] != C_NULL
@test fmi2StatusOK == fmi2FreeFMUstate(dlsym(lib,:fmi2FreeFMUstate), component, stateRef)
@test stateRef[] == C_NULL



# # Initialization Mode

@test fmi2StatusOK == fmi2EnterInitializationMode(dlsym(lib, :fmi2EnterInitializationMode), component)

fmireference = [fmi2ValueReference(16777220)]
@test fmi2StatusOK == fmi2SetReal(dlsym(lib, :fmi2SetReal), component, fmireference, Csize_t(1), fmi2Real.([0.8]))

fmireference = [fmi2ValueReference(16777220)]
value = zeros(fmi2Real, 1)
@test fmi2StatusOK == fmi2GetReal!(dlsym(lib, :fmi2GetReal), component, fmireference, Csize_t(1), value)
@test value == fmi2Real.([0.8])

fmireference = [fmi2ValueReference(637534208)]
value = zeros(fmi2Integer, 1)
@test fmi2StatusOK == fmi2GetInteger!(dlsym(lib, :fmi2GetInteger), component, fmireference, Csize_t(1), value)

fmireference = [fmi2ValueReference(637534208)]
@test fmi2StatusOK == fmi2SetInteger(dlsym(lib, :fmi2SetInteger), component, fmireference, Csize_t(1), fmi2Integer.([typemin(fmi2Integer)]))

fmireference = [fmi2ValueReference(637534208)]
value = zeros(fmi2Integer, 1)
@test fmi2StatusOK == fmi2GetInteger!(dlsym(lib, :fmi2GetInteger), component, fmireference, Csize_t(1), value)
@test value == fmi2Integer.([typemin(fmi2Integer)])

# calculate ∂p/∂p (x)
posreference = [fmi2ValueReference(33554432)]
delta_x = fmi2Real.([randn()])
result = zeros(fmi2Real, 1)
@test fmi2StatusOK == fmi2GetDirectionalDerivative!(dlsym(lib,:fmi2GetDirectionalDerivative), component, posreference, Csize_t(1), posreference, Csize_t(1), delta_x, result)
# ∂p/∂p(x) should be just x for any x
if Sys.WORD_SIZE == 64
# GetDirectionalDerivative behaves weirdly on 32 Bit
@test result ≈ delta_x
end

@test fmi2StatusOK == fmi2ExitInitializationMode(dlsym(lib, :fmi2ExitInitializationMode), component)

@test fmi2StatusOK == fmi2Reset(dlsym(lib, :fmi2Reset), component)

# # # fmi2FreeInstance
@test isnothing(fmi2FreeInstance(dlsym(lib, :fmi2FreeInstance), component))

end
Loading