source: trunk/Python/src/tests_jmodelica/general/test_extfunctions.py @ 13703

Last change on this file since 13703 was 13703, checked in by Christian Andersson, 2 months ago

Reverted changeset:13700. Related to ticket:5837

File size: 29.3 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (C) 2010-2017 Modelon AB
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, version 3 of the License.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17"""
18Module for testing external function support.
19"""
20import os, subprocess, shutil
21from os.path import join as path
22
23import nose
24
25from pymodelica import compile_fmu
26from pymodelica.common.core import get_platform_dir, create_temp_dir
27from pyfmi import load_fmu
28from pyfmi.fmi import FMUException
29from tests_jmodelica import testattr, get_files_path
30from tests_jmodelica.general.base_simul import *
31from assimulo.solvers.sundials import CVodeError
32
33path_to_mofiles = os.path.join(get_files_path(), 'Modelica')
34
35class TestExternalStatic:
36
37    @classmethod
38    def setUpClass(cls):
39        """
40        Sets up the test class.
41        """
42        cls.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
43   
44    @testattr(stddist_base = True)
45    def test_ExtFuncStatic(self):
46        """
47        Test compiling a model with external functions in a static library.
48        """
49        cpath = "ExtFunctionTests.ExtFunctionTest1"
50        fmu_name = compile_fmu(cpath, TestExternalStatic.fpath)
51        model = load_fmu(fmu_name)
52   
53    @testattr(stddist_base = True)
54    def test_IntegerArrays(self):
55        """
56        Test a model with external functions containing integer array and literal inputs.
57        """
58        cpath = "ExtFunctionTests.ExtFunctionTest4"
59        fmu_name = compile_fmu(cpath, TestExternalStatic.fpath, compiler_options={'variability_propagation':False})
60        model = load_fmu(fmu_name)
61        res = model.simulate()
62       
63        nose.tools.assert_equals(res.final('myResult[1]'), 2) 
64        nose.tools.assert_equals(res.final('myResult[2]'), 4)
65        nose.tools.assert_equals(res.final('myResult[3]'), 6)
66       
67class TestUtilities:
68   
69    @testattr(stddist_base = True)
70    def test_ModelicaUtilities(self):
71        """
72        Test compiling a model with external functions using the functions in ModelicaUtilities.
73        """
74        fpath = path(get_files_path(), 'Modelica', "ExtFunctionTests.mo")
75        cpath = "ExtFunctionTests.ExtFunctionTest3"
76        fmu_name = compile_fmu(cpath, fpath, compiler_options={'variability_propagation':False})
77        model = load_fmu(fmu_name)
78        #model.simulate()
79
80class TestExternalShared:
81   
82    @classmethod
83    def setUpClass(self):
84        """
85        Sets up the test class.
86        """
87        self.cpath = "ExtFunctionTests.ExtFunctionTest1"
88        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
89       
90    @testattr(stddist_base = True)
91    def test_ExtFuncShared(self):
92        """
93        Test compiling a model with external functions in a shared library. Simple.
94        """
95        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False})
96        model = load_fmu(fmu_name)
97        res = model.simulate()
98        nose.tools.assert_equals(res.final('c'), 3) 
99       
100    @testattr(stddist_base = True)
101    def test_ExtFuncSharedCeval(self):
102        """
103        Test compiling a model with external functions in a shared library. Constant evaluation during compilation.
104        """
105        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True})
106        model = load_fmu(fmu_name)
107        nose.tools.assert_equals(model.get('c'), 3)
108       
109    @testattr(stddist_full = True)
110    def test_ExtFuncSharedCevalDisabled(self):
111        """
112        Test compiling a model with external functions in a shared library. Disabling external evaluation during
113        variability propagation.
114        """
115        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True,
116            'variability_propagation_external':False})
117        model = load_fmu(fmu_name)
118        nose.tools.assert_equals(model.get_variable_variability('c'), 1)
119
120class TestExternalBool:
121   
122    @classmethod
123    def setUpClass(self):
124        """
125        Sets up the test class.
126        """
127        self.cpath = "ExtFunctionTests.ExtFunctionBool"
128        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
129       
130    @testattr(stddist_full = True)
131    def test_ExtFuncBool(self):
132        """
133        Test compiling a model with external functions in a shared library. Boolean arrays.
134        """
135        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False})
136        model = load_fmu(fmu_name)
137        model.simulate()
138        trueInd  = {1,2,3,5,8}
139        falseInd = {4,6,7}
140        for i in trueInd:
141            assert(model.get('res[' + str(i) + ']'))
142        for i in falseInd:
143            assert(not model.get('res[' + str(i) + ']'))
144
145class TestExternalRecord(SimulationTest):
146    @classmethod
147    def setUpClass(cls):
148        SimulationTest.setup_class_base('ExtFunctionTests.mo', 
149            'ExtFunctionTests.ExtFunctionRecord')
150
151    @testattr(stddist_full = True)
152    def setUp(self):
153        self.setup_base(start_time=0.0, final_time=0.1, time_step=0.01)
154        self.run()
155
156    @testattr(stddist_full = True)
157    def test_result(self):
158        self.assert_end_value('y.x', 0.1)
159
160class TestExternalRecordCeval(SimulationTest):
161    @classmethod
162    def setUpClass(cls):
163        SimulationTest.setup_class_base('ExtFunctionTests.mo', 
164            'ExtFunctionTests.ExtFunctionRecordCeval')
165
166    @testattr(stddist_full = True)
167    def setUp(self):
168        self.setup_base(start_time=0.0, final_time=0.1, time_step=0.01)
169        self.run()
170
171    @testattr(stddist_full = True)
172    def test_result(self):
173        self.assert_end_value('y1.x', 3)
174        self.assert_end_value('y2.x', 3)
175
176
177class TestExternalRecordObj(SimulationTest):
178    @classmethod
179    def setUpClass(cls):
180        SimulationTest.setup_class_base('ExtFunctionTests.mo', 
181            'ExtFunctionTests.ExtFunctionRecordObj')
182
183    @testattr(stddist_full = True)
184    def setUp(self):
185        self.setup_base(start_time=0.0, final_time=0.1, time_step=0.01)
186        self.run()
187
188    @testattr(stddist_full = True)
189    def test_result(self):
190        self.assert_end_value('y', 3)
191
192class TestExternalRecordObjCeval(SimulationTest):
193    @classmethod
194    def setUpClass(cls):
195        SimulationTest.setup_class_base('ExtFunctionTests.mo', 
196            'ExtFunctionTests.ExtFunctionRecordObjCeval')
197
198    @testattr(stddist_full = True)
199    def setUp(self):
200        self.setup_base(start_time=0.0, final_time=0.1, time_step=0.01)
201        self.run()
202
203    @testattr(stddist_full = True)
204    def test_result(self):
205        self.assert_end_value('y', 3)
206
207
208class TestExternalShared2:
209   
210    @classmethod
211    def setUpClass(self):
212        """
213        Sets up the test class.
214        """
215        self.cpath = "ExtFunctionTests.ExtFunctionTest2"
216        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
217       
218    @testattr(stddist_base = True)
219    def test_ExtFuncShared(self):
220        """
221        Test compiling a model with external functions in a shared library. Real, Integer, and Boolean arrays.
222        Compare results between constant evaluation and simulation.
223        """
224        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':True})
225        model = load_fmu(fmu_name)
226        s_ceval = model.get('s')
227        res = model.simulate()
228        s_sim1 = res.final('s')
229       
230        fmu_name = compile_fmu(self.cpath, self.fpath, compiler_options={'variability_propagation':False})
231        model = load_fmu(fmu_name)
232        res = model.simulate()
233        s_sim2 = res.final('s')
234        nose.tools.assert_equals(s_sim1, s_sim2)
235       
236class TestExternalInf:
237   
238    @classmethod
239    def setUpClass(self):
240        """
241        Sets up the test class. Check timeout of infinite loop during constant evaluation.
242        """
243        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
244       
245    @testattr(stddist_full = True)
246    def test_InfiniteLoopExternalEvaluation(self):
247        """
248        Test compiling a model with external functions in a shared library. Infinite loop.
249        """
250        fmu_name = compile_fmu("ExtFunctionTests.ExternalInfinityTest", self.fpath)
251       
252    @testattr(stddist_full = True)
253    def test_InfiniteLoopExternalEvaluationError(self):
254        """
255        Test compiling a model with external functions in a shared library. Infinite loop.
256        """
257        try:
258            fmu_name = compile_fmu("ExtFunctionTests.ExternalInfinityTestCeval", self.fpath, compiler_options={"external_constant_evaluation":100}, compiler_log_level="e:e.txt")
259        except:
260            pass
261        file=open("e.txt")
262        i = 0
263        for line in file.readlines():
264            if "timed out" in line:
265                i = i+1
266        assert i == 1, 'Wrong error message'
267       
268class TestExternalObject:
269   
270    @classmethod
271    def setUpClass(cls):
272        """
273        Sets up the test class.
274        """
275        cls.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
276       
277    @testattr(stddist_base = True)
278    def test_ExtObjectDestructor(self):
279        """
280        Test compiling a model with external object functions in a static library.
281        """
282        cpath = 'ExtFunctionTests.ExternalObjectTests1'
283        fmu_name = compile_fmu(cpath, TestExternalObject.fpath)
284        model = load_fmu(fmu_name)
285        model.simulate()
286        model.terminate()
287        if (os.path.exists('test_ext_object.marker')):
288             os.remove('test_ext_object.marker')
289        else:
290            assert False, 'External object destructor not called.'
291           
292class TestExternalObject2:
293   
294    @classmethod
295    def setUpClass(cls):
296        """
297        Sets up the test class.
298        """
299        cls.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
300       
301    @testattr(stddist_full = True)
302    def test_ExtObjectDestructor(self):
303        """
304        Test compiling a model with external object functions in a static library.
305        """
306        cpath = 'ExtFunctionTests.ExternalObjectTests2'
307        fmu_name = compile_fmu(cpath, TestExternalObject2.fpath)
308        model = load_fmu(fmu_name)
309        model.simulate()
310        model.terminate()
311        if (os.path.exists('test_ext_object_array1.marker') and os.path.exists('test_ext_object_array2.marker')):
312             os.remove('test_ext_object_array1.marker')
313             os.remove('test_ext_object_array2.marker')
314        else:
315            assert False, 'External object destructor not called.'
316           
317class TestExternalObject3:
318   
319    @classmethod
320    def setUpClass(cls):
321        """
322        Sets up the test class.
323        """
324        cls.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
325       
326    @testattr(stddist_full = True)
327    def test_ExtObjectDestructor(self):
328        cpath = 'ExtFunctionTests.ExternalObjectTests3'
329        fmu_name = compile_fmu(cpath, TestExternalObject2.fpath)
330        model = load_fmu(fmu_name, log_level=6)
331        model.set("_log_level", 6)
332        model.simulate()
333        model.terminate() #Test that we do not segfault at this point
334        log = model.get_log()[-1]
335        assert "This should not lead to a segfault" in log
336           
337class TestExternalObjectConstructorSingleCall:
338   
339    @classmethod
340    def setUpClass(cls):
341        """
342        Sets up the test class.
343        """
344        cls.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
345       
346    @testattr(stddist_full = True)
347    def test_ExtObjectConstructor(self):
348        """
349        Test independent external object constructor is called once
350        """
351        cpath = 'ExtFunctionTests.ConstructorSingleCallTest'
352        fmu_name = compile_fmu(cpath, TestExternalObjectConstructorSingleCall.fpath)
353        model = load_fmu(fmu_name)
354        model.simulate()
355        model.terminate()
356
357    @testattr(stddist_full = True)
358    def test_ExtObjectConstructorDependent(self):
359        """
360        Test external object constructor dependent on parameter is called once
361        """
362        cpath = 'ExtFunctionTests.ConstructorSingleCallDepTest'
363        fmu_name = compile_fmu(cpath, TestExternalObjectConstructorSingleCall.fpath)
364        model = load_fmu(fmu_name)
365        model.simulate()
366        model.terminate()
367
368    @testattr(stddist_full = True)
369    def test_ExtObjectConstructorDependentSetParam(self):
370        """
371        Test external object constructor dependent on parameter is not called when setting parameters
372        """
373        cpath = 'ExtFunctionTests.ConstructorSingleCallDepTest'
374        fmu_name = compile_fmu(cpath, TestExternalObjectConstructorSingleCall.fpath)
375        model = load_fmu(fmu_name)
376        model.set('s', 'test')
377        model.set('s', 'test2')
378        model.simulate()
379        model.terminate()
380
381class TestAssertEqu3(SimulationTest):
382    '''Test structural verification assert'''
383    @classmethod
384    def setUpClass(cls):
385        SimulationTest.setup_class_base(
386            "ExtFunctionTests.mo",
387            'ExtFunctionTests.StructuralAsserts')
388           
389    @testattr(stddist_base = True)
390    def test_simulate(self):
391        try:
392            self.setup_base()
393            self.run()
394            assert False, 'Simulation not stopped by failed assertions'
395        except FMUException, e:
396            pass
397   
398class TestModelicaError:
399   
400    @classmethod
401    def setUpClass(cls):
402        """
403        Sets up the test class.
404        """
405        cls.fpath = path(path_to_mofiles, 'Asserts.mo')
406       
407    @testattr(stddist_full = True)
408    def test_simulate(self):
409        cpath = 'Asserts.ModelicaError'
410        fmu_name = compile_fmu(cpath, TestModelicaError.fpath)
411        model = load_fmu(fmu_name)
412        try:
413            model.simulate(final_time = 3, options={"CVode_options":{"minh":1e-15}})
414            assert False, 'Simulation not stopped by calls to ModelicaError()'
415        except CVodeError, e:
416            assert abs(e.t - 2.0) < 0.01, 'Simulation stopped at wrong time'
417       
418
419class TestStrings:
420    @classmethod
421    def setUpClass(self):
422        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
423       
424    @testattr(stddist_full = True)
425    def testTmpString(self):
426        '''
427        Test that strings are propagated correctly
428        '''
429        cpath = "ExtFunctionTests.TestString"
430        fmu_name = compile_fmu(cpath, self.fpath, compiler_options={"variability_propagation":False, "inline_functions":"none"})
431        model = load_fmu(fmu_name)
432        res = model.simulate() #No asserts should be raised (in the model)
433
434       
435class TestCBasic:
436    '''
437    Test basic external C functions.
438    '''
439    @classmethod
440    def setUpClass(self):
441        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
442   
443    @testattr(stddist_full = True)
444    def testCEvalReal(self):
445        '''
446        Constant evaluation of basic external C function with Reals.
447        '''
448        cpath = "ExtFunctionTests.CEval.C.RealTest"
449        fmu_name = compile_fmu(cpath, self.fpath)
450        model = load_fmu(fmu_name)
451        res = model.simulate()
452        nose.tools.assert_equals(res.final('xScalar'), 3*3.14)
453        nose.tools.assert_equals(res.final('xArray[2]'), 4)
454        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), 6)
455       
456    @testattr(stddist_full = True)
457    def testCEvalInteger(self):
458        '''
459        Constant evaluation of basic external C function with Integers.
460        '''
461        cpath = "ExtFunctionTests.CEval.C.IntegerTest"
462        fmu_name = compile_fmu(cpath, self.fpath)
463        model = load_fmu(fmu_name)
464        res = model.simulate()
465        nose.tools.assert_equals(res.final('xScalar'), 9)
466        nose.tools.assert_equals(res.final('xArray[2]'), 4)
467        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), 6)
468   
469    @testattr(stddist_full = True)
470    def testCEvalBoolean(self):
471        '''
472        Constant evaluation of basic external C function with Booleans.
473        '''
474        cpath = "ExtFunctionTests.CEval.C.BooleanTest"
475        fmu_name = compile_fmu(cpath, self.fpath)
476        model = load_fmu(fmu_name)
477        res = model.simulate()
478        nose.tools.assert_equals(res.final('xScalar'), False)
479        nose.tools.assert_equals(res.final('xArray[2]'), True)
480        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), False)
481
482    @testattr(stddist_full = True)
483    def test_ExtFuncString(self):
484        cpath = "ExtFunctionTests.CEval.C.StringTest"
485        fmu_name = compile_fmu(cpath, self.fpath)
486        model = load_fmu(fmu_name)
487        res = model.simulate()
488        nose.tools.assert_equals(model.get('len'), 5)
489        #TODO: enable when model.get_string implemented
490        #nose.tools.assert_equals(model.get('xScalar'), 'dcb')
491        #nose.tools.assert_equals(model.get('xScalarLit'), 'dcb')
492        #nose.tools.assert_equals(model.get('xArray[2]'), 'dbf')
493        #nose.tools.assert_equals(model.get('xArrayUnknown[2]'), 'dbf')
494   
495    @testattr(stddist_full = True)
496    def testCEvalEnum(self):
497        '''
498        Constant evaluation of basic external C function with Enums.
499        '''
500        cpath = "ExtFunctionTests.CEval.C.EnumTest"
501        fmu_name = compile_fmu(cpath, self.fpath)
502        model = load_fmu(fmu_name)
503        res = model.simulate()
504        nose.tools.assert_equals(model.get('xScalar'), 2)
505        nose.tools.assert_equals(model.get('xArray[2]'), 2)
506        nose.tools.assert_equals(model.get('xArrayUnknown[2]'), 1)
507       
508    @testattr(stddist_full = True)
509    def testCEvalShortClass(self):
510        '''
511        Constant evaluation of function modified by short class decl
512        '''
513        cpath = "ExtFunctionTests.CEval.C.ShortClass"
514        fmu_name = compile_fmu(cpath, self.fpath)
515        model = load_fmu(fmu_name)
516        resConst = model.simulate()
517        nose.tools.assert_almost_equal(resConst.final('a1'), 10*3.14)
518
519    @testattr(stddist_full = True)
520    def testCEvalPackageConstant(self):
521        cpath = "ExtFunctionTests.CEval.C.PackageConstantTest"
522        fmu_name = compile_fmu(cpath, self.fpath)
523        model = load_fmu(fmu_name)
524        res = model.simulate()
525        nose.tools.assert_equals(res.final('x[2]'), 4)
526
527class TestFortranBasic:
528    '''
529    Test basic external fortran functions.
530    '''
531    @classmethod
532    def setUpClass(self):
533        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
534   
535    @testattr(stddist_base = True)
536    def testCEvalReal(self):
537        '''
538        Constant evaluation of basic external fortran function with Reals.
539        '''
540        cpath = "ExtFunctionTests.CEval.Fortran.RealTest"
541        fmu_name = compile_fmu(cpath, self.fpath)
542        model = load_fmu(fmu_name)
543        res = model.simulate()
544        nose.tools.assert_equals(res.final('xScalar'), 3*3.14)
545        nose.tools.assert_equals(res.final('xArray[2]'), 4)
546        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), 6)
547       
548    @testattr(stddist_base = True)
549    def testCEvalMatrixReal(self):
550        '''
551        Constant evaluation of basic external fortran function with Reals.
552        '''
553        cpath = "ExtFunctionTests.CEval.Fortran.RealTestMatrix"
554        fmu_name = compile_fmu(cpath, self.fpath)
555        model = load_fmu(fmu_name)
556        res = model.simulate()
557        nose.tools.assert_equals(res.final('y1[1,1]'), 1)
558        nose.tools.assert_equals(res.final('y2[1,1]'), 9)
559       
560    @testattr(stddist_base = True)
561    def testCEvalInteger(self):
562        '''
563        Constant evaluation of basic external fortran function with Integers.
564        '''
565        cpath = "ExtFunctionTests.CEval.Fortran.IntegerTest"
566        fmu_name = compile_fmu(cpath, self.fpath)
567        model = load_fmu(fmu_name)
568        res = model.simulate()
569        nose.tools.assert_equals(res.final('xScalar'), 9)
570        nose.tools.assert_equals(res.final('xArray[2]'), 4)
571        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), 6)
572   
573    @testattr(stddist_full = True)
574    def testCEvalBoolean(self):
575        '''
576        Constant evaluation of basic external fortran function with Booleans.
577        '''
578        cpath = "ExtFunctionTests.CEval.Fortran.BooleanTest"
579        fmu_name = compile_fmu(cpath, self.fpath)
580        model = load_fmu(fmu_name)
581        res = model.simulate()
582        nose.tools.assert_equals(res.final('xScalar'), False)
583        nose.tools.assert_equals(res.final('xArray[2]'), True)
584        nose.tools.assert_equals(res.final('xArrayUnknown[2]'), False)
585   
586    @testattr(stddist_full = True)
587    def testCEvalEnum(self):
588        '''
589        Constant evaluation of basic external fortran function with Enums.
590        '''
591        cpath = "ExtFunctionTests.CEval.Fortran.EnumTest"
592        fmu_name = compile_fmu(cpath, self.fpath)
593        model = load_fmu(fmu_name)
594        res = model.simulate()
595        nose.tools.assert_equals(model.get('xScalar'), 2)
596        nose.tools.assert_equals(model.get('xArray[2]'), 2)
597        nose.tools.assert_equals(model.get('xArrayUnknown[2]'), 1)
598       
599class TestAdvanced:
600    '''
601    Test advanced external fortran functions.
602    '''
603    @classmethod
604    def setUpClass(self):
605        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
606   
607    @testattr(stddist_base = True)
608    def testDGELSX(self):
609        '''
610        A test using the external fortran function dgelsx from lapack.
611        Compares simulation results with constant evaluation results.
612        '''
613        cpath = "ExtFunctionTests.CEval.Advanced.DgelsxTest"
614        fmu_name = compile_fmu(cpath, self.fpath, compiler_options={'variability_propagation':False})
615        model = load_fmu(fmu_name)
616        resSim = model.simulate()
617        fmu_name = compile_fmu(cpath, self.fpath, compiler_options={'variability_propagation':True})
618        model = load_fmu(fmu_name)
619        resConst = model.simulate()
620        for i in range(1,4):
621          for j in range(1,4):
622            x = 'out[{0},{1}]'.format(i,j)
623            nose.tools.assert_almost_equals(resSim.final(x), resConst.final(x), places=13)
624        nose.tools.assert_equals(resSim.final('a'), resConst.final('a'))
625        nose.tools.assert_equals(resSim.final('b'), resConst.final('b'))
626       
627    @testattr(stddist_base = True)
628    def testExtObjScalar(self):
629        '''
630        Test constant evaluation of a simple external object.
631        '''
632        cpath = "ExtFunctionTests.CEval.Advanced.ExtObjTest1"
633        fmu_name = compile_fmu(cpath, self.fpath)
634        model = load_fmu(fmu_name)
635        resConst = model.simulate()
636        nose.tools.assert_equals(resConst.final('x'), 6.13)
637       
638    @testattr(stddist_base = True)
639    def testExtObjArrays(self):
640        '''
641        Test constant evaluation of arrays of external objects.
642        '''
643        cpath = "ExtFunctionTests.CEval.Advanced.ExtObjTest2"
644        fmu_name = compile_fmu(cpath, self.fpath)
645        model = load_fmu(fmu_name)
646        resConst = model.simulate()
647        nose.tools.assert_equals(resConst.final('x'), 13.27)
648       
649    @testattr(stddist_full = True)
650    def testExtObjRecursive(self):
651        '''
652        Test constant evaluation of external object encapsulating
653        external objects.
654        '''
655        cpath = "ExtFunctionTests.CEval.Advanced.ExtObjTest3"
656        fmu_name = compile_fmu(cpath, self.fpath)
657        model = load_fmu(fmu_name)
658        resConst = model.simulate()
659        nose.tools.assert_equals(resConst.final('x'), 32.67)
660   
661    @testattr(stddist_full = True)
662    def testPartialEvalFail(self):
663        '''
664        Test failing of partial constant evaluation on external function
665        '''
666        cpath = "ExtFunctionTests.CEval.Advanced.UnknownInput"
667        fmu_name = compile_fmu(cpath, self.fpath, version=1.0) 
668        model = load_fmu(fmu_name)
669        assert model.get_variable_variability("y") == 3, 'y should be continuous'
670       
671        fmu_name = compile_fmu(cpath, self.fpath, version=2.0) #Continuous variability is == 4 with FMI2
672        model = load_fmu(fmu_name)
673        assert model.get_variable_variability("y") == 4, 'y should be continuous'
674       
675       
676   
677class TestUtilitiesCEval:
678    '''
679    Test utility functions in external C functions.
680    '''
681    @classmethod
682    def setUpClass(self):
683        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
684   
685    @testattr(stddist_base = True)
686    def testCEvalLog(self):
687        '''
688        Constant evaluation of external C logging function.
689        '''
690        cpath = "ExtFunctionTests.CEval.Utility.LogTest"
691        fmu_name = compile_fmu(cpath, self.fpath, compiler_log_level="w:tmp.log")
692        logfile = open('tmp.log')
693        count = 0
694        for line in logfile:
695            if line == "ModelicaMessage: <msg:X is a bit high: 1.100000.>\n" or line == "ModelicaError: <msg:X is too high: 2.100000.>\n":
696                count = count + 1
697        logfile.close()
698        os.remove(logfile.name);
699        assert(count >= 2)
700
701class TestCevalCaching:
702    '''
703    Test caching of external objects during constant evaluation
704    '''
705    @classmethod
706    def setUpClass(self):
707        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
708   
709    @testattr(stddist_full = True)
710    def testCaching1(self):
711        '''
712        Test caching of external objects during constant evaluation
713        '''
714        cpath = "ExtFunctionTests.CEval.Caching.CacheExtObj"
715        fmu_name = compile_fmu(cpath, self.fpath)
716        model = load_fmu(fmu_name)
717        res = model.simulate()
718        nose.tools.assert_equals(res.final('n3'), 5)
719       
720    @testattr(stddist_full = True)
721    def testCaching2(self):
722        '''
723        Test caching process limit of external objects during constant evaluation
724        '''
725        cpath = "ExtFunctionTests.CEval.Caching.CacheExtObjLimit"
726        fmu_name = compile_fmu(cpath, self.fpath, compiler_options={'external_constant_evaluation_max_proc':2})
727        model = load_fmu(fmu_name)
728        res = model.simulate()
729        nose.tools.assert_equals(res.final('n3'), 20)
730       
731    @testattr(stddist_full = True)
732    def testCaching3(self):
733        '''
734        Test disabling process caching
735        '''
736        cpath = "ExtFunctionTests.CEval.Caching.CacheExtObj"
737        fmu_name = compile_fmu(cpath, self.fpath, compiler_options={'external_constant_evaluation_max_proc':0})
738        model = load_fmu(fmu_name)
739        res = model.simulate()
740        nose.tools.assert_equals(res.final('n3'), 4)
741       
742    @testattr(stddist_full = True)
743    def testConError(self):
744        '''
745        Test caching of external objects during constant evaluation, ModelicaError in constructor.
746        '''
747        cpath = "ExtFunctionTests.CEval.Caching.ConError"
748        fmu_name = compile_fmu(cpath, self.fpath)
749       
750    @testattr(stddist_full = True)
751    def testDeconError(self):
752        '''
753        Test caching of external objects during constant evaluation, ModelicaError in deconstructor.
754        '''
755        cpath = "ExtFunctionTests.CEval.Caching.DeconError"
756        fmu_name = compile_fmu(cpath, self.fpath)
757       
758    @testattr(stddist_full = True)
759    def testUseError(self):
760        '''
761        Test caching of external objects during constant evaluation, ModelicaError in use.
762        '''
763        cpath = "ExtFunctionTests.CEval.Caching.UseError"
764        fmu_name = compile_fmu(cpath, self.fpath)
765       
766       
767    @testattr(stddist_full = True)
768    def testConCrash(self):
769        '''
770        Test caching of external objects during constant evaluation, Crash in constructor.
771        '''
772        cpath = "ExtFunctionTests.CEval.Caching.ConCrash"
773        fmu_name = compile_fmu(cpath, self.fpath)
774       
775    @testattr(stddist_full = True)
776    def testDeconCrash(self):
777        '''
778        Test caching of external objects during constant evaluation, Crash in deconstructor.
779        '''
780        cpath = "ExtFunctionTests.CEval.Caching.DeconCrash"
781        fmu_name = compile_fmu(cpath, self.fpath)
782       
783    @testattr(stddist_full = True)
784    def testUseCrash(self):
785        '''
786        Test caching of external objects during constant evaluation, Crash in use.
787        '''
788        cpath = "ExtFunctionTests.CEval.Caching.UseCrash"
789        fmu_name = compile_fmu(cpath, self.fpath)
790       
791class TestMultiUse:
792    @classmethod
793    def setUpClass(self):
794        self.fpath = path(path_to_mofiles, "ExtFunctionTests.mo")
795   
796    @testattr(stddist_full = True)
797    def testMultiUse1(self):
798        cpath = "ExtFunctionTests.MultiUse1"
799        fmu_name = compile_fmu(cpath, self.fpath)
800        model = load_fmu(fmu_name)
801        res = model.simulate()
802        nose.tools.assert_equals(res.final('y'), 5.0)
Note: See TracBrowser for help on using the repository browser.