]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil.core/native/FMILibrary/Test/FMI1/fmi1_capi_cs_test.c
Merge remote-tracking branch 'origin/master' into release/1.35.1
[simantics/fmil.git] / org.simantics.fmil.core / native / FMILibrary / Test / FMI1 / fmi1_capi_cs_test.c
1 /*
2     Copyright (C) 2012 Modelon AB
3
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the BSD style license.
6
7      This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10     FMILIB_License.txt file for more details.
11
12     You should have received a copy of the FMILIB_License.txt file
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <errno.h>
21
22 #include <JM/jm_types.h>
23 #include <JM/jm_portability.h>
24 #include <FMI1/fmi1_types.h>
25 #include <FMI1/fmi1_functions.h>
26 #include <FMI1/fmi1_capi.h>
27 #include <JM/jm_callbacks.h>
28 #include <fmu_dummy/fmu1_model_defines.h>
29 #include "config_test.h" /* Defines path to the DLL file */
30
31
32 #define MODEL_IDENTIFIER FMU_DUMMY_CS_MODEL_IDENTIFIER
33
34 /* #define PRINT_VERBOSE */
35 #define INSTANCE_NAME           "Test Model"
36
37 fmi1_capi_t* fmu; /* Pointer to the C-API struct that is used in all tests */
38
39 /* Logger function used by the C-API */
40 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
41 {
42         printf("module = %s, log level = %d: %s\n", module, log_level, message);
43 }
44
45 /* Logger function used by the FMU internally */
46 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
47 {
48         char msg[BUFFER];
49     int len;
50         va_list argp;   
51         va_start(argp, message);
52         len=jm_vsnprintf(msg, BUFFER, message, argp);
53         printf("fmiStatus = %d;  %s (%s): %s\n", status, instanceName, category, msg);
54     if(len > BUFFER) {
55         printf("Warning: message was trancated");
56     }
57 }
58
59 /* Pause and exit function. Useally called when an error occured */
60 void do_exit(int code)
61 {
62         printf("Press any key to exit\n");
63         /* getchar(); */
64         exit(code);
65 }
66
67 jm_callbacks* callbacks = 0;
68
69 /**
70  * \brief Tests fmi1_capi_create_dllfmu
71  *
72  */
73 int test_create_dllfmu()
74 {
75         fmi1_callback_functions_t callBackFunctions;
76         fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone; 
77
78         callbacks = calloc(1, sizeof(jm_callbacks));
79
80         callbacks->malloc = malloc;
81     callbacks->calloc = calloc;
82     callbacks->realloc = realloc;
83     callbacks->free = free;
84     callbacks->logger = importlogger;
85     callbacks->log_level = jm_log_level_debug;
86     callbacks->context = 0;
87
88         callBackFunctions.logger = fmilogger;
89         callBackFunctions.allocateMemory = calloc;
90         callBackFunctions.freeMemory = free;
91
92         printf("fmi1_capi_create_dllfmu:                 ");
93         fmu = fmi1_capi_create_dllfmu(callbacks, FMU1_DLL_CS_PATH, MODEL_IDENTIFIER_STR, callBackFunctions, standard);
94         if (fmu == NULL) {
95                 printf("An error occured while fmi1_capi_create_dllfmu was called, an error message should been printed.\n");
96                 do_exit(CTEST_RETURN_FAIL);;
97         } else {
98                 printf("Success\n");
99         }
100         return 0;
101 }
102
103 /**
104  * \brief Tests fmi1_capi_load_dll
105  *
106  */
107 int test_load_dll()
108 {
109         jm_status_enu_t status;
110
111         printf("fmi1_capi_load_dll:                      ");
112         status = fmi1_capi_load_dll(fmu);
113         if (status == jm_status_error) {
114                 printf("Error in fmi1_capi_load_dll: %s\n", jm_get_last_error(callbacks));
115                 do_exit(CTEST_RETURN_FAIL);;
116         } else {
117                 printf("Success\n");
118         }
119         return 0;
120 }
121
122 /**
123  * \brief Tests fmi1_capi_load_fcn
124  *
125  */
126 int test_load_dll_fcn()
127 {
128         jm_status_enu_t status;
129
130         printf("fmi1_capi_load_fcn:                      ");
131         status = fmi1_capi_load_fcn(fmu);
132         if (status == jm_status_error) {
133                 printf("\n");
134                 printf("Error in fmi1_capi_load_fcn: %s\n", "fmi1_capi_get_last_error(fmu)");
135                 do_exit(CTEST_RETURN_FAIL);;
136         } else {                
137                 printf("Success\n");
138         }
139         return 0;
140 }
141
142 /**
143  * \brief Tests fmi1_capi_get_version
144  *
145  */
146 int test_fmi_get_version()
147 {
148         const char* version = fmi1_capi_get_version(fmu);
149
150         printf("fmi1_capi_get_version:                   ");
151         if (strcmp(FMI_VERSION, version) != 0) {
152                 printf("Expected \"%s\" but returned \"%s\"", FMI_VERSION, version);
153                 do_exit(CTEST_RETURN_FAIL);;
154         } else {
155                 printf("Success\n");
156         }
157         return 0;
158 }
159
160 /**
161  * \brief Tests fmi1_capi_get_types_platform
162  *
163  */
164 int test_get_types_platform()
165 {
166         const char* platformtype = fmi1_capi_get_types_platform(fmu);
167
168         printf("fmi1_capi_get_types_platform:            ");
169         if (strcmp(FMI_PLATFORM_TYPE, platformtype) != 0) {
170                 printf("Expected \"%s\" but returned \"%s\"", FMI_PLATFORM_TYPE, platformtype);
171                 do_exit(CTEST_RETURN_FAIL);;
172         } else {
173                 printf("Success\n");
174         }
175         return 0;
176 }
177
178 /**
179  * \brief Tests fmi1_capi_instantiate_slave
180  *
181  */
182 int test_instantiate_slave()
183 {
184         fmi1_string_t fmuLocation;
185         fmi1_string_t mimeType;
186         fmi1_real_t timeout;
187         fmi1_boolean_t visible;
188         fmi1_boolean_t interactive;
189         fmi1_boolean_t loggingOn;
190
191         fmuLocation = "";
192         mimeType = "";
193         timeout = 0;
194         visible = fmi1_false;
195         interactive = fmi1_false;
196         loggingOn = fmi1_true;
197
198         if (fmi1_capi_instantiate_slave(fmu, INSTANCE_NAME, FMI_GUID, fmuLocation, mimeType, timeout, visible, interactive, loggingOn) == NULL) {               
199                 printf("fmi1_capi_instantiate_slave:             Failed\n");
200                 do_exit(CTEST_RETURN_FAIL);;
201         } else {
202                 printf("fmi1_capi_instantiate_slave:             Success\n");
203         }
204         return 0;
205 }
206
207 /**
208  * \brief Tests fmi1_capi_initialize_slave
209  *
210  */
211 int test_initialize_slave()
212 {
213         fmi1_status_t status;
214         fmi1_real_t tStart;
215         fmi1_real_t tStop;
216         fmi1_boolean_t StopTimeDefined;
217
218         tStart = 0;
219         tStop = 10;
220         StopTimeDefined = fmi1_false;
221
222         status = fmi1_capi_initialize_slave(fmu, tStart, StopTimeDefined, tStop);
223         if (status == fmi1_status_error || status == fmi1_status_fatal) {
224                 printf("fmi1_capi_initialize_slave:              Failed\n");
225                 do_exit(CTEST_RETURN_FAIL);;
226         } else {
227                 printf("fmi1_capi_initialize_slave:              Success\n");
228         }
229         return 0;
230 }
231
232 /**
233  * \brief Tests fmi1_capi_set_debug_logging
234  *
235  */
236 int test_set_debug_logging()
237 {
238         fmi1_status_t status;
239         status = fmi1_capi_set_debug_logging(fmu, fmi1_true);
240         if (status == fmi1_status_error || status == fmi1_status_fatal) {
241                 printf("fmi1_capi_set_debug_logging:             Failed\n");
242                 do_exit(CTEST_RETURN_FAIL);;
243         } else {
244                 printf("fmi1_capi_set_debug_logging:             Success\n");
245         }
246         return 0;
247 }
248
249 /**
250  * \brief Tests fmi1_capi_cancel_step
251  *
252  */
253 int test_cancel_step()
254 {
255         fmi1_status_t status;
256         status = fmi1_capi_cancel_step(fmu);
257         if (status == fmi1_status_error || status == fmi1_status_fatal) {
258                 printf("fmi1_capi_cancel_step:                   Failed\n");
259                 do_exit(CTEST_RETURN_FAIL);;
260         } else {
261                 printf("fmi1_capi_cancel_step:                   Success\n");
262         }
263         return 0;
264 }
265
266 /**
267  * \brief Tests fmi1_capi_do_step
268  *
269  */
270 int test_do_step()
271 {
272         fmi1_status_t status;
273         fmi1_real_t currentCommunicationPoint;
274         fmi1_real_t communicationStepSize; 
275         fmi1_boolean_t newStep;
276
277         currentCommunicationPoint = 0;
278         communicationStepSize = 0.1;
279         newStep = fmi1_true;
280         status = fmi1_capi_do_step(fmu, currentCommunicationPoint, communicationStepSize, newStep);
281         if (status == fmi1_status_error || status == fmi1_status_fatal) {
282                 printf("fmi1_capi_do_step:                       Failed\n");
283                 do_exit(CTEST_RETURN_FAIL);;
284         } else {
285                 printf("fmi1_capi_do_step:                       Success\n");
286         }
287         return 0;
288 }
289
290 /**
291  * \brief Tests fmi1_capi_get_status
292  *
293  */
294 int test_get_status()
295 {
296         fmi1_status_t status;
297         fmi1_status_kind_t statuskind;
298         fmi1_status_t  statusvalue;
299
300         statuskind = fmi1_do_step_status;
301         status = fmi1_capi_get_status(fmu, statuskind, &statusvalue);
302         if (status == fmi1_status_error || status == fmi1_status_fatal) {
303                 printf("fmi1_capi_get_status:                    Failed\n");
304                 do_exit(CTEST_RETURN_FAIL);;
305         } else {
306                 printf("fmi1_capi_get_status:                    Success\n");
307         }
308         return 0;
309 }
310
311 /**
312  * \brief Tests fmi1_capi_get_real_status
313  *
314  */
315 int test_get_real_status()
316 {
317         fmi1_status_t status;
318         fmi1_status_kind_t statuskind = fmi1_last_successful_time;
319         fmi1_real_t real;
320
321         status = fmi1_capi_get_real_status(fmu, statuskind, &real);
322         if (status == fmi1_status_error || status == fmi1_status_fatal) {
323                 printf("fmi1_capi_get_real_status:               Failed\n");
324                 do_exit(CTEST_RETURN_FAIL);;
325         } else {
326                 printf("fmi1_capi_get_real_status:               Success\n");
327         }
328         return 0;
329 }
330
331 /**
332  * \brief Tests fmi1_capi_get_integer_status
333  *
334  */
335 int test_get_integer_status()
336 {
337         fmi1_status_t status;
338         fmi1_status_kind_t statuskind = fmi1_last_successful_time;
339         fmi1_integer_t integer;
340
341         status = fmi1_capi_get_integer_status(fmu, statuskind, &integer);
342         if (status != fmi1_status_discard) {
343                 printf("fmi1_capi_get_integer_status:            Failed\n");
344                 do_exit(CTEST_RETURN_FAIL);;
345         } else {
346                 printf("fmi1_capi_get_integer_status:            Success\n");
347         }
348         return 0;
349 }
350
351 /**
352  * \brief Tests fmi1_capi_get_boolean_status
353  *
354  */
355 int test_get_boolean_status()
356 {
357         fmi1_status_t status;
358         fmi1_status_kind_t statuskind = fmi1_last_successful_time;
359         fmi1_boolean_t boolean;
360
361         status = fmi1_capi_get_boolean_status(fmu, statuskind, &boolean);
362         if (status != fmi1_status_discard) {
363                 printf("fmi1_capi_get_boolean_status:            Failed\n");
364                 do_exit(CTEST_RETURN_FAIL);;
365         } else {
366                 printf("fmi1_capi_get_boolean_status:            Success\n");
367         }
368         return 0;
369 }
370
371 /**
372  * \brief Tests fmi1_capi_get_string_status
373  *
374  */
375 int test_get_string_status()
376 {
377         fmi1_status_t status;
378         fmi1_status_kind_t statuskind = fmi1_pending_status;
379         fmi1_string_t string;
380
381         status = fmi1_capi_get_string_status(fmu, statuskind, &string);
382         if (status != fmi1_status_discard) {
383                 printf("fmi1_capi_get_string_status:             Failed\n");
384                 do_exit(CTEST_RETURN_FAIL);;
385         } else {
386                 printf("fmi1_capi_get_string_status:             Success\n");
387         }
388         return 0;
389 }
390
391 /**
392  * \brief Tests fmi1_capi_set_string and fmi1_capi_get_string
393  * Some values are set with fmi1_capi_set_string. The same values are retrived with fmi1_capi_get_string and tested to be the same as thoughs that were set.
394  */
395 int test_set_get_string()
396 {
397         fmi1_status_t status;
398         fmi1_value_reference_t vrs[N_STRING];
399         fmi1_string_t values[N_STRING];
400         fmi1_string_t values_ref[N_STRING];
401         size_t k;
402
403         for (k = 0; k < N_STRING; k++) {
404                 vrs[k] = (fmi1_value_reference_t)k;
405                 values[k] = "hej";
406                 values_ref[k] = values[k];
407         }
408
409         /* Test fmi1_capi_set_string */
410         status = fmi1_capi_set_string(fmu, vrs, N_STRING, values);
411         if (status == fmi1_status_error || status == fmi1_status_fatal) {
412                 printf("fmi1_capi_set_string:                    Failed\n");
413                 do_exit(CTEST_RETURN_FAIL);;
414         } else {
415                 printf("fmi1_capi_set_string:                    Success\n");
416         }
417
418         /* Test fmi1_capi_get_string */
419         status = fmi1_capi_get_string(fmu, vrs, N_STRING, values);
420         if (status == fmi1_status_error || status == fmi1_status_fatal) {
421                 printf("fmi1_capi_get_string:                    Failed\n");
422                 do_exit(CTEST_RETURN_FAIL);;
423         } else {
424                 for (k = 0; k < N_STRING; k++) {
425                         if (strcmp(values_ref[k], values[k]) != 0) {
426                                 printf("fmi1_capi_get_string returned values[%u] = \"%s\" expected \"%s\"\n", (unsigned)k, values[k], values_ref[k]);
427                                 do_exit(CTEST_RETURN_FAIL);;
428                         }
429                 }
430                 printf("fmi1_capi_get_string:                    Success\n");
431         }
432
433         return 0;
434 }
435
436 /**
437  * \brief Tests fmi1_capi_set_integer and fmi1_capi_get_integer
438  * Some values are set with fmi1_capi_set_integer. The same values are retrived with fmi1_capi_get_integer and tested to be the same as thoughs that were set.
439  */
440 int test_set_get_integer()
441 {
442         fmi1_status_t status;
443         fmi1_value_reference_t vrs[N_INTEGER];
444         fmi1_integer_t values[N_INTEGER];
445         fmi1_integer_t values_ref[N_INTEGER];
446         int k;
447
448         for (k = 0; k < N_INTEGER; k++) {
449                 vrs[k] = (fmi1_value_reference_t)k;
450                 values[k] = (k + 1) * 12;
451                 values_ref[k] = values[k];
452         }
453
454         /* Test fmi1_capi_set_integer */
455         status = fmi1_capi_set_integer(fmu, vrs, N_INTEGER, values);
456         if (status == fmi1_status_error || status == fmi1_status_fatal) {
457                 printf("fmi1_capi_set_integer:                   Failed\n");
458                 do_exit(CTEST_RETURN_FAIL);;
459         } else {
460                 printf("fmi1_capi_set_integer:                   Success\n");
461         }
462
463         /* Test fmi1_capi_get_integer */
464         status = fmi1_capi_get_integer(fmu, vrs, N_INTEGER, values);
465         if (status == fmi1_status_error || status == fmi1_status_fatal) {
466                 printf("fmi1_capi_get_integer:                   Failed\n");
467                 do_exit(CTEST_RETURN_FAIL);
468         } else {
469                 for (k = 0; k < N_INTEGER; k++) {
470                         if (values_ref[k] != values[k]) {
471                                 printf("fmi1_capi_get_integer returned values[%d] = \"%d\" expected \"%d\"\n", k, values[k], values_ref[k]);
472                                 do_exit(CTEST_RETURN_FAIL);
473                         }
474                 }
475                 printf("fmi1_capi_get_integer:                   Success\n");
476         }
477
478         return 0;
479 }
480
481 /**
482  * \brief Tests fmi1_capi_set_boolean and fmi1_capi_get_boolean
483  * Some values are set with fmi1_capi_set_boolean. The same values are retrived with fmi1_capi_get_boolean and tested to be the same as thoughs that were set.
484  */
485 int test_set_get_boolean()
486 {
487         fmi1_status_t status;
488         fmi1_value_reference_t vrs[N_BOOLEAN];
489         fmi1_boolean_t values[N_BOOLEAN];
490         fmi1_boolean_t values_ref[N_BOOLEAN];
491         size_t k;
492
493         for (k = 0; k < N_INTEGER; k++) {
494                 vrs[k] = (fmi1_value_reference_t)k;
495                 values[k] = fmi1_true;
496                 values_ref[k] = values[k];
497         }
498
499         /* Test fmi1_capi_set_boolean */
500         status = fmi1_capi_set_boolean(fmu, vrs, N_BOOLEAN, values);
501         if (status == fmi1_status_error || status == fmi1_status_fatal) {
502                 printf("fmi1_capi_set_boolean:                   Failed\n");
503                 do_exit(CTEST_RETURN_FAIL);
504         } else {
505                 printf("fmi1_capi_set_boolean:                   Success\n");
506         }
507
508         /* Test fmi1_capi_get_boolean */
509         status = fmi1_capi_get_boolean(fmu, vrs, N_BOOLEAN, values);
510         if (status == fmi1_status_error || status == fmi1_status_fatal) {
511                 printf("fmi1_capi_get_boolean:                   Failed\n");
512                 do_exit(CTEST_RETURN_FAIL);
513         } else {
514                 for (k = 0; k < N_BOOLEAN; k++) {
515                         if (values_ref[k] != values[k]) {
516                                 printf("fmi1_capi_get_boolean returned values[%u] = \"%s\" expected \"%s\"\n", (unsigned)k, values[k] ? "fmiTrue" : "fmiFalse", values_ref[k] ? "fmiTrue" : "fmiFalse");
517                                 do_exit(CTEST_RETURN_FAIL);
518                         }
519                 }
520                 printf("fmi1_capi_get_boolean:                   Success\n");
521         }
522
523         return 0;
524 }
525
526 /**
527  * \brief Tests fmi1_capi_set_real and fmi1_capi_get_real
528  * Some values are set with fmi1_capi_set_real. The same values are retrived with fmi1_capi_get_real and tested to be the same as thoughs that were set.
529  */
530 int test_set_get_real()
531 {
532         fmi1_status_t status;
533         fmi1_value_reference_t vrs[N_REAL];
534         fmi1_real_t values[N_REAL];
535         fmi1_real_t values_ref[N_REAL];
536         size_t k;
537
538         for (k = 0; k < N_REAL; k++) {
539                 vrs[k] = (fmi1_value_reference_t)(N_STATES + k);
540                 values[k] = (fmi1_real_t)(k + 1) * 12;
541                 values_ref[k] = values[k];
542         }
543
544         /* Test fmi1_capi_set_real */
545         status = fmi1_capi_set_real(fmu, vrs, N_REAL, values);
546         if (status == fmi1_status_error || status == fmi1_status_fatal) {
547                 printf("fmi1_capi_set_real:                      Failed\n");
548                 do_exit(CTEST_RETURN_FAIL);
549         } else {
550                 printf("fmi1_capi_set_real:                      Success\n");
551         }
552
553         /* Test fmi1_capi_get_real */
554         status = fmi1_capi_get_real(fmu, vrs, N_REAL, values);
555         if (status == fmi1_status_error || status == fmi1_status_fatal) {
556                 printf("fmi1_capi_get_real:                      Failed\n");
557                 do_exit(CTEST_RETURN_FAIL);
558         } else {
559                 for (k = 0; k < N_REAL; k++) {
560                         if (values_ref[k] != values[k]) {
561                                 printf("fmi1_capi_get_real returned values[%u] = \"%f\" expected \"%f\"\n", (unsigned)k, values[k], values_ref[k]);
562                                 do_exit(CTEST_RETURN_FAIL);
563                         }
564                 }
565                 printf("fmi1_capi_get_real:                      Success\n");
566         }
567
568         return 0;
569 }
570
571 /**
572  * \brief Tests fmi1_capi_reset_slave
573  * 
574  */
575 int test_reset_slave()
576 {
577         fmi1_status_t status;
578         status = fmi1_capi_reset_slave(fmu);
579         if (status == fmi1_status_error || status == fmi1_status_fatal) {
580                 printf("fmi1_capi_reset_slave:                   Failed\n");
581                 do_exit(CTEST_RETURN_FAIL);
582         } else {
583                 printf("fmi1_capi_reset_slave:                   Success\n");
584         }
585         return 0;
586 }
587
588 /**
589  * \brief Tests fmi1_capi_set_real_input_derivatives
590  * fmi1_capi_set_real_input_derivatives returns fmiError if wrong values are set. The values that are set are tested inside the DLL.
591  */
592 int test_set_real_input_derivatives()
593 {
594         fmi1_status_t status;
595         fmi1_value_reference_t  vrs             [N_INPUT_REAL * N_INPUT_REAL_MAX_ORDER];
596         fmi1_real_t                             values  [N_INPUT_REAL * N_INPUT_REAL_MAX_ORDER];
597         fmi1_integer_t                  order   [N_INPUT_REAL * N_INPUT_REAL_MAX_ORDER];
598         int k, p;
599
600         for (k = 0; k < N_INPUT_REAL_MAX_ORDER; k++) {
601                 for (p = 0; p < N_INPUT_REAL; p++)
602                 {
603                         vrs             [p + k * N_INPUT_REAL] = (fmi1_value_reference_t)p;
604                         values  [p + k * N_INPUT_REAL] = MAGIC_TEST_VALUE; /* This value is tested in the DLL to be exakt MAGIC_TEST_VALUE */
605                         order   [p + k * N_INPUT_REAL] = k + 1;
606                 }
607         }
608
609         status = fmi1_capi_set_real_input_derivatives(fmu, vrs, N_INPUT_REAL * N_INPUT_REAL_MAX_ORDER, order, values);
610         if (status == fmi1_status_error || status == fmi1_status_fatal) {
611                 printf("fmi1_capi_set_real_input_derivatives:    Failed\n");
612                 do_exit(CTEST_RETURN_FAIL);
613         } else {
614                 printf("fmi1_capi_set_real_input_derivatives:    Success\n");
615         }
616         return 0;
617 }
618
619 /**
620  * \brief Tests fmi1_capi_get_real_output_derivatives
621  * The output values from fmi1_capi_get_real_output_derivatives is expected to have a special value that is coded in the DLL. 
622  */
623 int test_get_real_output_derivatives()
624 {
625         fmi1_status_t status;
626         fmi1_value_reference_t  vrs             [N_OUTPUT_REAL * N_OUTPUT_REAL_MAX_ORDER];
627         fmi1_real_t                             values  [N_OUTPUT_REAL * N_OUTPUT_REAL_MAX_ORDER];
628         fmi1_integer_t                  order   [N_OUTPUT_REAL * N_OUTPUT_REAL_MAX_ORDER];
629         size_t k, p;
630
631         for (k = 0; k < N_OUTPUT_REAL_MAX_ORDER; k++) {
632                 for (p = 0; p < N_OUTPUT_REAL; p++)
633                 {
634                         vrs             [p + k * N_OUTPUT_REAL] = (fmi1_value_reference_t)p;
635                         values  [p + k * N_OUTPUT_REAL] = -1;
636                         order   [p + k * N_OUTPUT_REAL] = (fmi1_integer_t)k + 1;
637                 }
638         }
639
640         status = fmi1_capi_get_real_output_derivatives(fmu, vrs, N_INPUT_REAL * N_INPUT_REAL_MAX_ORDER, order, values);
641         if (status == fmi1_status_error || status == fmi1_status_fatal) {
642                 printf("fmi1_capi_get_real_output_derivatives:   Failed\n");
643                 do_exit(CTEST_RETURN_FAIL);
644         } else {
645                 printf("fmi1_capi_get_real_output_derivatives:   Success\n");
646
647                 for (k = 0; k < N_OUTPUT_REAL_MAX_ORDER; k++) {
648                         for (p = 0; p < N_OUTPUT_REAL; p++)
649                         {
650                                 fmi1_real_t value = values[p + k * N_OUTPUT_REAL];
651                                 if (value != MAGIC_TEST_VALUE) { /* This value is set in DLL to be exakt MAGIC_TEST_VALUE */
652                                         printf("fmi1_capi_get_real_output_derivatives:   Failed\n");
653                                         do_exit(CTEST_RETURN_FAIL);
654                                 }
655
656 #ifdef PRINT_VERBOSE
657                                 fmi1_integer_t ord = k + 1;
658                                 printf("value[%d][%d] = %f \n", p, ord, value);
659 #endif
660                         }
661                 }
662         }
663         return 0;
664 }
665
666 /**
667  * \brief Tests fmi1_capi_terminate_slave
668  *
669  */
670 int test_terminate_slave()
671 {
672         fmi1_status_t status;
673         status = fmi1_capi_terminate_slave(fmu);
674         if (status == fmi1_status_error || status == fmi1_status_fatal) {
675                 printf("fmi1_capi_terminate_slave:               Failed\n");
676                 do_exit(CTEST_RETURN_FAIL);
677         } else {
678                 printf("fmi1_capi_terminate_slave:               Success\n");
679         }
680         return 0;
681 }
682
683 /**
684  * \brief Tests fmi1_capi_free_slave_instance
685  *
686  */
687 int test_free_slave_instance()
688 {
689         fmi1_capi_free_slave_instance(fmu);
690         printf("fmi1_capi_free_slave_instance:           Success\n");           
691         return 0;
692 }
693
694 /**
695  * \brief Tests fmi1_capi_free_dll
696  *
697  */
698 int test_free_dll()
699 {
700         fmi1_capi_free_dll(fmu);
701         printf("fmi1_capi_free_dll:                      Success\n");
702         return 0;
703 }
704
705 /**
706  * \brief Tests fmi1_capi_destroy_dllfmu
707  *
708  */
709 int test_destroy_dllfmu()
710 {
711         fmi1_capi_destroy_dllfmu(fmu);
712         printf("fmi1_capi_destroy_dllfmu:                Success\n");
713         return 0;
714 }
715
716 /**
717  * \brief Tests the C-API for FMI 1.0 Co-Simulation.
718  * The tests are performed using a test-dll. The functions are called and the values are set or returned are validated either in the test function(output functions) or inside the dll(input functions). If any error occures, the program exits. 
719  *
720  */
721 int main(int argc, char *argv[])
722 {
723         /* Test CAPI constructor functions */
724         test_create_dllfmu();
725         test_load_dll();
726         test_load_dll_fcn();
727
728         /* FMI CS 1.0 functions */
729         test_instantiate_slave();
730         test_get_types_platform();      
731         test_initialize_slave();
732         test_cancel_step();
733         test_do_step();
734         test_get_status();
735         test_get_real_status();
736         test_get_integer_status();
737         test_get_boolean_status();
738         test_get_string_status();
739         test_reset_slave();
740         test_set_real_input_derivatives();
741         test_get_real_output_derivatives();
742
743         test_fmi_get_version();
744         test_set_get_string();
745         test_set_get_boolean();
746         test_set_get_integer();
747         test_set_get_real();
748         test_set_debug_logging();
749
750         test_terminate_slave();
751         test_free_slave_instance();
752
753         /* Test CAPI destructor functions */
754         test_free_dll();
755         test_destroy_dllfmu();
756         free(callbacks);
757         printf("\n");
758         printf("Everything seems to be ok!\n");
759         printf("\n");
760         do_exit(CTEST_RETURN_SUCCESS);
761         return 0;
762 }
763
764