]> gerrit.simantics Code Review - simantics/fmil.git/blobdiff - org.simantics.fmil.core/native/FMILibrary/Test/FMI1/fmi_import_cs_test.c
Add FMILibrary-2.0.3 to org.simantics.fmil.core\native.
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / Test / FMI1 / fmi_import_cs_test.c
diff --git a/org.simantics.fmil.core/native/FMILibrary/Test/FMI1/fmi_import_cs_test.c b/org.simantics.fmil.core/native/FMILibrary/Test/FMI1/fmi_import_cs_test.c
new file mode 100644 (file)
index 0000000..31b48df
--- /dev/null
@@ -0,0 +1,371 @@
+/*\r
+    Copyright (C) 2012 Modelon AB\r
+\r
+    This program is free software: you can redistribute it and/or modify\r
+    it under the terms of the BSD style license.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    FMILIB_License.txt file for more details.\r
+\r
+    You should have received a copy of the FMILIB_License.txt file\r
+    along with this program. If not, contact Modelon AB <http://www.modelon.com>.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+\r
+#include "config_test.h"\r
+\r
+#include <fmilib.h>\r
+\r
+\r
+#define BUFFER 1000\r
+\r
+void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)\r
+{\r
+        printf("module = %s, log level = %s: %s\n", module, jm_log_level_to_string(log_level), message);\r
+}\r
+\r
+/* Logger function used by the FMU internally */\r
+\r
+void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)\r
+{\r
+       /* char msg[BUFFER];*/\r
+       va_list argp;\r
+       va_start(argp, message);\r
+       /* vsnprintf(msg, BUFFER, message, argp); */\r
+       fmi1_log_forwarding_v(c, instanceName, status, category, message, argp);\r
+       va_end(argp);\r
+}\r
+\r
+void do_exit(int code)\r
+{\r
+       printf("Press 'Enter' to exit\n");\r
+       /* getchar(); */\r
+       exit(code);\r
+}\r
+\r
+/* Testing "...Test\FMI1\fmu_dummy\modelDescription_cs_tc.xml" */\r
+void test_xml_modelDescription_cs_tc(const char* xmlFileName, fmi1_import_t* fmu)\r
+{\r
+    fmi1_import_variable_t* v;\r
+\r
+    { /* Test variable "INTEGER" */\r
+        fmi1_import_integer_variable_t* vi;\r
+        const char* name = "INTEGER";\r
+        printf("Testing ScalarVariable %s\n", name);\r
+        v = fmi1_import_get_variable_by_name(fmu, name);\r
+        vi = fmi1_import_get_variable_as_integer(v);\r
+\r
+        /* Test min attr */\r
+        if (1 != fmi1_import_get_integer_variable_min(vi)) {\r
+            printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+\r
+        /* Test max attr */\r
+        if (11 != fmi1_import_get_integer_variable_max(vi)) {\r
+            printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+    }\r
+\r
+    { /* Test variable "INTEGER_DECLAREDTYPE" */\r
+        fmi1_import_integer_variable_t* vi;\r
+        const char* name = "INTEGER_DECLAREDTYPE";\r
+        printf("Testing ScalarVariable %s\n", name);\r
+        v = fmi1_import_get_variable_by_name(fmu, name);\r
+        vi = fmi1_import_get_variable_as_integer(v);\r
+\r
+        /* Test min attr */\r
+        if (2 != fmi1_import_get_integer_variable_min(vi)) {\r
+            printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+\r
+        /* Test max attr */\r
+        if (22 != fmi1_import_get_integer_variable_max(vi)) {\r
+            printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+    }\r
+\r
+    { /* Test variable "INTEGER_DECLAREDTYPE_OVERWRITE" */\r
+        fmi1_import_integer_variable_t* vi;\r
+        const char* name = "INTEGER_DECLAREDTYPE_OVERWRITE";\r
+        printf("Testing ScalarVariable %s\n", name);\r
+        v = fmi1_import_get_variable_by_name(fmu, name);\r
+        vi = fmi1_import_get_variable_as_integer(v);\r
+\r
+        /* Test min attr */\r
+        if (1 != fmi1_import_get_integer_variable_min(vi)) {\r
+            printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+\r
+        /* Test max attr */\r
+        if (11 != fmi1_import_get_integer_variable_max(vi)) {\r
+            printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+    }\r
+\r
+    { /* Test variable "ENUMERATION_DECLAREDTYPE" */\r
+        fmi1_import_enum_variable_t* vi;\r
+        const char* name = "ENUMERATION_DECLAREDTYPE";\r
+        printf("Testing ScalarVariable %s\n", name);\r
+        v = fmi1_import_get_variable_by_name(fmu, name);\r
+        vi = fmi1_import_get_variable_as_enum(v);\r
+\r
+        /* Test min attr */\r
+        if (1 != fmi1_import_get_enum_variable_min(vi)) {\r
+            printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+\r
+        /* Test max attr */\r
+        if (5 != fmi1_import_get_enum_variable_max(vi)) {\r
+            printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+    }\r
+\r
+    { /* Test variable "ENUMERATION_DECLAREDTYPE_OVERWRITE" */\r
+        fmi1_import_enum_variable_t* vi;\r
+        const char* name = "ENUMERATION_DECLAREDTYPE_OVERWRITE";\r
+        printf("Testing ScalarVariable %s\n", name);\r
+        v = fmi1_import_get_variable_by_name(fmu, name);\r
+        vi = fmi1_import_get_variable_as_enum(v);\r
+\r
+        /* Test min attr */\r
+        if (2 != fmi1_import_get_enum_variable_min(vi)) {\r
+            printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+\r
+        /* Test max attr */\r
+        if (3 != fmi1_import_get_enum_variable_max(vi)) {\r
+            printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);\r
+            do_exit(CTEST_RETURN_FAIL);\r
+        }\r
+    }\r
+}\r
+\r
+typedef struct {\r
+       const char* filename;\r
+       int performTest;\r
+       void (*fcn)(const char* xmlFileName, fmi1_import_t* fmu);\r
+} xml_test_files_t;\r
+\r
+xml_test_files_t xml_test_files[] = {\r
+       {"modelDescription_cs_tc.xml", 1, test_xml_modelDescription_cs_tc},\r
+       {"modelDescription_cs.xml", 0, NULL}\r
+};\r
+\r
+void test_xml(const char* xmlFileName, fmi1_import_t* fmu)\r
+{\r
+    int k;\r
+    int foundxml = 0;\r
+\r
+    for (k = 0; k < sizeof(xml_test_files)/sizeof(*xml_test_files); k++) {\r
+        foundxml = strcmp(xmlFileName, xml_test_files[k].filename) == 0 ? 1 : 0;\r
+        if (foundxml) {\r
+            if (xml_test_files[k].performTest) {\r
+                xml_test_files[k].fcn(xmlFileName, fmu); /* Run specific file XML file test */\r
+            }\r
+            return;\r
+        }\r
+    }\r
+\r
+    if (!foundxml) {\r
+        printf("XML file test is not properly implemented in " __FILE__ " . Could not find the XML \"%s\" in the list of expected XML-files", xmlFileName);\r
+        do_exit(CTEST_RETURN_FAIL);\r
+    }\r
+}\r
+\r
+\r
+int test_simulate_cs(fmi1_import_t* fmu)\r
+{\r
+       fmi1_status_t fmistatus;\r
+       jm_status_enu_t jmstatus;\r
+\r
+       fmi1_string_t instanceName = "Test CS model instance";\r
+       fmi1_string_t fmuGUID;\r
+       fmi1_string_t fmuLocation = "";\r
+       fmi1_string_t mimeType = "";\r
+       fmi1_real_t timeout = 0.0;\r
+       fmi1_boolean_t visible = fmi1_false;\r
+       fmi1_boolean_t interactive = fmi1_false;\r
+/*     fmi1_boolean_t loggingOn = fmi1_true; */\r
+\r
+       /* fmi1_real_t simulation_results[] = {-0.001878, -1.722275}; */\r
+       fmi1_real_t simulation_results[] = {0.0143633,   -1.62417};\r
+       fmi1_value_reference_t compare_real_variables_vr[] = {0, 1};\r
+       size_t k;\r
+\r
+       fmi1_real_t tstart = 0.0;\r
+       fmi1_real_t tcur = tstart;\r
+       fmi1_real_t hstep = 0.1;\r
+       fmi1_real_t tend = 2.0;\r
+       fmi1_boolean_t StopTimeDefined = fmi1_false;\r
+\r
+       if (sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t) != sizeof(simulation_results)/sizeof(fmi1_real_t)) {\r
+               printf("Number of simulation values and reference values are different\n");\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+\r
+       printf("Version returned from FMU:   %s\n", fmi1_import_get_version(fmu));\r
+       printf("Platform type returned:      %s\n", fmi1_import_get_types_platform(fmu));\r
+\r
+       fmuGUID = fmi1_import_get_GUID(fmu);\r
+    printf("GUID:      %s\n", fmuGUID);\r
+\r
+\r
+       jmstatus = fmi1_import_instantiate_slave(fmu, instanceName, fmuLocation, mimeType, timeout, visible, interactive);\r
+       if (jmstatus == jm_status_error) {\r
+               printf("fmi1_import_instantiate_model failed\n");\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+\r
+       fmistatus = fmi1_import_initialize_slave(fmu, tstart, StopTimeDefined, tend);\r
+    if(fmistatus != fmi1_status_ok) {\r
+        printf("fmi1_import_initialize_slave failed\n");\r
+               do_exit(CTEST_RETURN_FAIL);\r
+    }\r
+\r
+       tcur = tstart;\r
+       printf("%10s %10s\n", "Ball height", "Ball speed");\r
+       while (tcur < tend) {\r
+               fmi1_boolean_t newStep = fmi1_true;\r
+#if 0 /* Prints a real value.. */\r
+               fmi1_real_t rvalue;\r
+               fmi1_value_reference_t vr = 0;\r
+\r
+               fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);\r
+               printf("rvalue = %f\n", rvalue);\r
+#endif\r
+               fmistatus = fmi1_import_do_step(fmu, tcur, hstep, newStep);\r
+\r
+               for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t); k++) {\r
+                       fmi1_value_reference_t vr = compare_real_variables_vr[k];\r
+                       fmi1_real_t rvalue;\r
+                       fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);\r
+               }\r
+               {\r
+                       fmi1_real_t val[2];\r
+                       fmi1_import_get_real(fmu, compare_real_variables_vr, 2, val);\r
+                       printf("%10g %10g\n", val[0],val[1]);\r
+               }\r
+\r
+               tcur += hstep;\r
+       }\r
+\r
+       printf("Simulation finished. Checking results\n");\r
+\r
+       /* Validate result */\r
+       for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t); k++) {\r
+               fmi1_value_reference_t vr = compare_real_variables_vr[k];\r
+               fmi1_real_t rvalue;\r
+               fmi1_real_t res;\r
+               fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);\r
+               res = rvalue - simulation_results[k];\r
+               res = res > 0 ? res: -res; /* Take abs */\r
+               if (res > 3e-3) {\r
+                       printf("Simulation results is wrong!\n");\r
+                       printf("State [%u]  %g != %g, |res| = %g\n", (unsigned)k, rvalue, simulation_results[k], res);\r
+                       printf("\n");\r
+                       do_exit(CTEST_RETURN_FAIL);\r
+               }\r
+       }\r
+\r
+       fmistatus = fmi1_import_terminate_slave(fmu);\r
+\r
+       fmi1_import_free_slave_instance(fmu);\r
+\r
+       return 0;\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+       fmi1_callback_functions_t callBackFunctions;\r
+       const char* FMUPath;\r
+       const char* tmpPath;\r
+       const char* xmlFileName;\r
+       jm_callbacks callbacks;\r
+       fmi_import_context_t* context;\r
+       fmi_version_enu_t version;\r
+       jm_status_enu_t status;\r
+       int k;\r
+\r
+       fmi1_import_t* fmu;\r
+\r
+       if(argc < 4) {\r
+               printf("Usage: %s <fmu_file> <temporary_dir> <modelDescription_file>\n", argv[0]);\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+       for (k = 0; k < argc; k ++)\r
+               printf("argv[%d] = %s\n", k, argv[k]);\r
+\r
+       FMUPath = argv[1];\r
+       tmpPath = argv[2];\r
+       xmlFileName = argv[3];\r
+\r
+       callbacks.malloc = malloc;\r
+    callbacks.calloc = calloc;\r
+    callbacks.realloc = realloc;\r
+    callbacks.free = free;\r
+    callbacks.logger = importlogger;\r
+       callbacks.log_level = jm_log_level_debug;\r
+    callbacks.context = 0;\r
+\r
+       callBackFunctions.logger = fmi1_log_forwarding;\r
+       callBackFunctions.allocateMemory = calloc;\r
+       callBackFunctions.freeMemory = free;\r
+\r
+#ifdef FMILIB_GENERATE_BUILD_STAMP\r
+       printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());\r
+#endif\r
+\r
+       context = fmi_import_allocate_context(&callbacks);\r
+\r
+       version = fmi_import_get_fmi_version(context, FMUPath, tmpPath);\r
+\r
+       if(version != fmi_version_1_enu) {\r
+               printf("Only version 1.0 is supported so far\n");\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+\r
+       fmu = fmi1_import_parse_xml(context, tmpPath);\r
+\r
+       if(!fmu) {\r
+               printf("Error parsing XML, exiting\n");\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+\r
+\r
+       status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 1);\r
+       if (status == jm_status_error) {\r
+               printf("Could not create the DLL loading mechanism(C-API) (error: %s).\n", fmi1_import_get_last_error(fmu));\r
+               do_exit(CTEST_RETURN_FAIL);\r
+       }\r
+\r
+       test_simulate_cs(fmu);\r
+       test_xml(xmlFileName, fmu);\r
+\r
+       fmi1_import_destroy_dllfmu(fmu);\r
+\r
+       fmi1_import_free(fmu);\r
+       fmi_import_free_context(context);\r
+\r
+       printf("Everything seems to be OK since you got this far=)!\n");\r
+\r
+       do_exit(CTEST_RETURN_SUCCESS);\r
+\r
+       return 0;\r
+}\r
+\r
+\r