2 Copyright (C) 2012 Modelon AB
\r
4 This program is free software: you can redistribute it and/or modify
\r
5 it under the terms of the BSD style license.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
10 FMILIB_License.txt file for more details.
\r
12 You should have received a copy of the FMILIB_License.txt file
\r
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
\r
21 #include "config_test.h"
\r
28 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
\r
30 printf("module = %s, log level = %s: %s\n", module, jm_log_level_to_string(log_level), message);
\r
33 /* Logger function used by the FMU internally */
\r
35 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
\r
37 /* char msg[BUFFER];*/
\r
39 va_start(argp, message);
\r
40 /* vsnprintf(msg, BUFFER, message, argp); */
\r
41 fmi1_log_forwarding_v(c, instanceName, status, category, message, argp);
\r
45 void do_exit(int code)
\r
47 printf("Press 'Enter' to exit\n");
\r
52 /* Testing "...Test\FMI1\fmu_dummy\modelDescription_cs_tc.xml" */
\r
53 void test_xml_modelDescription_cs_tc(const char* xmlFileName, fmi1_import_t* fmu)
\r
55 fmi1_import_variable_t* v;
\r
57 { /* Test variable "INTEGER" */
\r
58 fmi1_import_integer_variable_t* vi;
\r
59 const char* name = "INTEGER";
\r
60 printf("Testing ScalarVariable %s\n", name);
\r
61 v = fmi1_import_get_variable_by_name(fmu, name);
\r
62 vi = fmi1_import_get_variable_as_integer(v);
\r
65 if (1 != fmi1_import_get_integer_variable_min(vi)) {
\r
66 printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);
\r
67 do_exit(CTEST_RETURN_FAIL);
\r
71 if (11 != fmi1_import_get_integer_variable_max(vi)) {
\r
72 printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);
\r
73 do_exit(CTEST_RETURN_FAIL);
\r
77 { /* Test variable "INTEGER_DECLAREDTYPE" */
\r
78 fmi1_import_integer_variable_t* vi;
\r
79 const char* name = "INTEGER_DECLAREDTYPE";
\r
80 printf("Testing ScalarVariable %s\n", name);
\r
81 v = fmi1_import_get_variable_by_name(fmu, name);
\r
82 vi = fmi1_import_get_variable_as_integer(v);
\r
85 if (2 != fmi1_import_get_integer_variable_min(vi)) {
\r
86 printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);
\r
87 do_exit(CTEST_RETURN_FAIL);
\r
91 if (22 != fmi1_import_get_integer_variable_max(vi)) {
\r
92 printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);
\r
93 do_exit(CTEST_RETURN_FAIL);
\r
97 { /* Test variable "INTEGER_DECLAREDTYPE_OVERWRITE" */
\r
98 fmi1_import_integer_variable_t* vi;
\r
99 const char* name = "INTEGER_DECLAREDTYPE_OVERWRITE";
\r
100 printf("Testing ScalarVariable %s\n", name);
\r
101 v = fmi1_import_get_variable_by_name(fmu, name);
\r
102 vi = fmi1_import_get_variable_as_integer(v);
\r
104 /* Test min attr */
\r
105 if (1 != fmi1_import_get_integer_variable_min(vi)) {
\r
106 printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);
\r
107 do_exit(CTEST_RETURN_FAIL);
\r
110 /* Test max attr */
\r
111 if (11 != fmi1_import_get_integer_variable_max(vi)) {
\r
112 printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);
\r
113 do_exit(CTEST_RETURN_FAIL);
\r
117 { /* Test variable "ENUMERATION_DECLAREDTYPE" */
\r
118 fmi1_import_enum_variable_t* vi;
\r
119 const char* name = "ENUMERATION_DECLAREDTYPE";
\r
120 printf("Testing ScalarVariable %s\n", name);
\r
121 v = fmi1_import_get_variable_by_name(fmu, name);
\r
122 vi = fmi1_import_get_variable_as_enum(v);
\r
124 /* Test min attr */
\r
125 if (1 != fmi1_import_get_enum_variable_min(vi)) {
\r
126 printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);
\r
127 do_exit(CTEST_RETURN_FAIL);
\r
130 /* Test max attr */
\r
131 if (5 != fmi1_import_get_enum_variable_max(vi)) {
\r
132 printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);
\r
133 do_exit(CTEST_RETURN_FAIL);
\r
137 { /* Test variable "ENUMERATION_DECLAREDTYPE_OVERWRITE" */
\r
138 fmi1_import_enum_variable_t* vi;
\r
139 const char* name = "ENUMERATION_DECLAREDTYPE_OVERWRITE";
\r
140 printf("Testing ScalarVariable %s\n", name);
\r
141 v = fmi1_import_get_variable_by_name(fmu, name);
\r
142 vi = fmi1_import_get_variable_as_enum(v);
\r
144 /* Test min attr */
\r
145 if (2 != fmi1_import_get_enum_variable_min(vi)) {
\r
146 printf("Test of XML file \"%s\" failed. min attribute value missmatch.\n", xmlFileName);
\r
147 do_exit(CTEST_RETURN_FAIL);
\r
150 /* Test max attr */
\r
151 if (3 != fmi1_import_get_enum_variable_max(vi)) {
\r
152 printf("Test of XML file \"%s\" failed. max attribute value missmatch.\n", xmlFileName);
\r
153 do_exit(CTEST_RETURN_FAIL);
\r
159 const char* filename;
\r
161 void (*fcn)(const char* xmlFileName, fmi1_import_t* fmu);
\r
162 } xml_test_files_t;
\r
164 xml_test_files_t xml_test_files[] = {
\r
165 {"modelDescription_cs_tc.xml", 1, test_xml_modelDescription_cs_tc},
\r
166 {"modelDescription_cs.xml", 0, NULL}
\r
169 void test_xml(const char* xmlFileName, fmi1_import_t* fmu)
\r
174 for (k = 0; k < sizeof(xml_test_files)/sizeof(*xml_test_files); k++) {
\r
175 foundxml = strcmp(xmlFileName, xml_test_files[k].filename) == 0 ? 1 : 0;
\r
177 if (xml_test_files[k].performTest) {
\r
178 xml_test_files[k].fcn(xmlFileName, fmu); /* Run specific file XML file test */
\r
185 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
186 do_exit(CTEST_RETURN_FAIL);
\r
191 int test_simulate_cs(fmi1_import_t* fmu)
\r
193 fmi1_status_t fmistatus;
\r
194 jm_status_enu_t jmstatus;
\r
196 fmi1_string_t instanceName = "Test CS model instance";
\r
197 fmi1_string_t fmuGUID;
\r
198 fmi1_string_t fmuLocation = "";
\r
199 fmi1_string_t mimeType = "";
\r
200 fmi1_real_t timeout = 0.0;
\r
201 fmi1_boolean_t visible = fmi1_false;
\r
202 fmi1_boolean_t interactive = fmi1_false;
\r
203 /* fmi1_boolean_t loggingOn = fmi1_true; */
\r
205 /* fmi1_real_t simulation_results[] = {-0.001878, -1.722275}; */
\r
206 fmi1_real_t simulation_results[] = {0.0143633, -1.62417};
\r
207 fmi1_value_reference_t compare_real_variables_vr[] = {0, 1};
\r
210 fmi1_real_t tstart = 0.0;
\r
211 fmi1_real_t tcur = tstart;
\r
212 fmi1_real_t hstep = 0.1;
\r
213 fmi1_real_t tend = 2.0;
\r
214 fmi1_boolean_t StopTimeDefined = fmi1_false;
\r
216 if (sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t) != sizeof(simulation_results)/sizeof(fmi1_real_t)) {
\r
217 printf("Number of simulation values and reference values are different\n");
\r
218 do_exit(CTEST_RETURN_FAIL);
\r
221 printf("Version returned from FMU: %s\n", fmi1_import_get_version(fmu));
\r
222 printf("Platform type returned: %s\n", fmi1_import_get_types_platform(fmu));
\r
224 fmuGUID = fmi1_import_get_GUID(fmu);
\r
225 printf("GUID: %s\n", fmuGUID);
\r
228 jmstatus = fmi1_import_instantiate_slave(fmu, instanceName, fmuLocation, mimeType, timeout, visible, interactive);
\r
229 if (jmstatus == jm_status_error) {
\r
230 printf("fmi1_import_instantiate_model failed\n");
\r
231 do_exit(CTEST_RETURN_FAIL);
\r
234 fmistatus = fmi1_import_initialize_slave(fmu, tstart, StopTimeDefined, tend);
\r
235 if(fmistatus != fmi1_status_ok) {
\r
236 printf("fmi1_import_initialize_slave failed\n");
\r
237 do_exit(CTEST_RETURN_FAIL);
\r
241 printf("%10s %10s\n", "Ball height", "Ball speed");
\r
242 while (tcur < tend) {
\r
243 fmi1_boolean_t newStep = fmi1_true;
\r
244 #if 0 /* Prints a real value.. */
\r
245 fmi1_real_t rvalue;
\r
246 fmi1_value_reference_t vr = 0;
\r
248 fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);
\r
249 printf("rvalue = %f\n", rvalue);
\r
251 fmistatus = fmi1_import_do_step(fmu, tcur, hstep, newStep);
\r
253 for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t); k++) {
\r
254 fmi1_value_reference_t vr = compare_real_variables_vr[k];
\r
255 fmi1_real_t rvalue;
\r
256 fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);
\r
259 fmi1_real_t val[2];
\r
260 fmi1_import_get_real(fmu, compare_real_variables_vr, 2, val);
\r
261 printf("%10g %10g\n", val[0],val[1]);
\r
267 printf("Simulation finished. Checking results\n");
\r
269 /* Validate result */
\r
270 for (k = 0; k < sizeof(compare_real_variables_vr)/sizeof(fmi1_value_reference_t); k++) {
\r
271 fmi1_value_reference_t vr = compare_real_variables_vr[k];
\r
272 fmi1_real_t rvalue;
\r
274 fmistatus = fmi1_import_get_real(fmu, &vr, 1, &rvalue);
\r
275 res = rvalue - simulation_results[k];
\r
276 res = res > 0 ? res: -res; /* Take abs */
\r
278 printf("Simulation results is wrong!\n");
\r
279 printf("State [%u] %g != %g, |res| = %g\n", (unsigned)k, rvalue, simulation_results[k], res);
\r
281 do_exit(CTEST_RETURN_FAIL);
\r
285 fmistatus = fmi1_import_terminate_slave(fmu);
\r
287 fmi1_import_free_slave_instance(fmu);
\r
292 int main(int argc, char *argv[])
\r
294 fmi1_callback_functions_t callBackFunctions;
\r
295 const char* FMUPath;
\r
296 const char* tmpPath;
\r
297 const char* xmlFileName;
\r
298 jm_callbacks callbacks;
\r
299 fmi_import_context_t* context;
\r
300 fmi_version_enu_t version;
\r
301 jm_status_enu_t status;
\r
304 fmi1_import_t* fmu;
\r
307 printf("Usage: %s <fmu_file> <temporary_dir> <modelDescription_file>\n", argv[0]);
\r
308 do_exit(CTEST_RETURN_FAIL);
\r
310 for (k = 0; k < argc; k ++)
\r
311 printf("argv[%d] = %s\n", k, argv[k]);
\r
315 xmlFileName = argv[3];
\r
317 callbacks.malloc = malloc;
\r
318 callbacks.calloc = calloc;
\r
319 callbacks.realloc = realloc;
\r
320 callbacks.free = free;
\r
321 callbacks.logger = importlogger;
\r
322 callbacks.log_level = jm_log_level_debug;
\r
323 callbacks.context = 0;
\r
325 callBackFunctions.logger = fmi1_log_forwarding;
\r
326 callBackFunctions.allocateMemory = calloc;
\r
327 callBackFunctions.freeMemory = free;
\r
329 #ifdef FMILIB_GENERATE_BUILD_STAMP
\r
330 printf("Library build stamp:\n%s\n", fmilib_get_build_stamp());
\r
333 context = fmi_import_allocate_context(&callbacks);
\r
335 version = fmi_import_get_fmi_version(context, FMUPath, tmpPath);
\r
337 if(version != fmi_version_1_enu) {
\r
338 printf("Only version 1.0 is supported so far\n");
\r
339 do_exit(CTEST_RETURN_FAIL);
\r
342 fmu = fmi1_import_parse_xml(context, tmpPath);
\r
345 printf("Error parsing XML, exiting\n");
\r
346 do_exit(CTEST_RETURN_FAIL);
\r
350 status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 1);
\r
351 if (status == jm_status_error) {
\r
352 printf("Could not create the DLL loading mechanism(C-API) (error: %s).\n", fmi1_import_get_last_error(fmu));
\r
353 do_exit(CTEST_RETURN_FAIL);
\r
356 test_simulate_cs(fmu);
\r
357 test_xml(xmlFileName, fmu);
\r
359 fmi1_import_destroy_dllfmu(fmu);
\r
361 fmi1_import_free(fmu);
\r
362 fmi_import_free_context(context);
\r
364 printf("Everything seems to be OK since you got this far=)!\n");
\r
366 do_exit(CTEST_RETURN_SUCCESS);
\r