]> SALOME platform Git repositories - tools/eficas.git/blob - Aster/Cata/cataSTA10/Macro/test_fichier_ops.py
Salome HOME
Modif V6_4_°
[tools/eficas.git] / Aster / Cata / cataSTA10 / Macro / test_fichier_ops.py
1 #@ MODIF test_fichier_ops Macro  DATE 10/11/2009   AUTEUR COURTOIS M.COURTOIS 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2004  EDF R&D                  WWW.CODE-ASTER.ORG
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; EITHER VERSION 2 OF THE LICENSE, OR     
9 # (AT YOUR OPTION) ANY LATER VERSION.                                                  
10 #                                                                       
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT   
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF            
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU      
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                              
15 #                                                                       
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE     
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,         
18 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.        
19 # ======================================================================
20
21 import sys
22 import os
23 import re
24
25 # hashlib only exists in python>=2.5
26 def hash_new():
27    try:
28       import hashlib
29       _hash_new = hashlib.md5()
30       print 'hashlib'
31    except ImportError:
32       import md5
33       _hash_new = md5.new()
34       print 'md5'
35    return _hash_new
36
37
38 class TestFichierError(Exception):
39    pass
40
41
42 def convert(x):
43    return float(x)
44
45 def f_SOMM(somme, lx):
46    return somme + sum([convert(x) for x in lx])
47
48 def f_SOMM_ABS(somme, lx):
49    return somme + sum([abs(convert(x)) for x in lx])
50
51 def f_MINI(val, lx):
52    return min(val, min([convert(x) for x in lx]))
53
54 def f_MAXI(val, lx):
55    return max(val, max([convert(x) for x in lx]))
56
57 def f_MINI_ABS(val, lx):
58    return min(val, min([abs(convert(x)) for x in lx]))
59
60 def f_MAXI_ABS(val, lx):
61    return max(val, max([abs(convert(x)) for x in lx]))
62
63 dict_func_test = {
64    'SOMM'     : f_SOMM,
65    'SOMM_ABS' : f_SOMM_ABS,
66    'MINI'     : f_MINI,
67    'MAXI'     : f_MAXI,
68    'MINI_ABS' : f_MINI_ABS,
69    'MAXI_ABS' : f_MAXI_ABS,
70 }
71
72 #-------------------------------------------------------------------------------
73 def test_fichier_ops(self, FICHIER, NB_VALE, VALE, VALE_K, TYPE_TEST,
74                            CRITERE, PRECISION, INFO, **kwargs):
75    """
76      Macro permettant de tester la non-regression d'un fichier.
77      On teste le nombre de réels présents, et, facultativement, la
78      somme de ces nombres et le texte du fichier.
79    """
80    ier = 0
81    # La macro compte pour 1 dans la numerotation des commandes
82    self.set_icmd(1)
83
84    # On importe les definitions des commandes a utiliser dans la macro
85    # Le nom de la variable doit etre obligatoirement le nom de la commande
86    INFO_EXEC_ASTER = self.get_cmd('INFO_EXEC_ASTER')
87    DETRUIRE        = self.get_cmd('DETRUIRE')
88    CREA_TABLE      = self.get_cmd('CREA_TABLE')
89    TEST_TABLE      = self.get_cmd('TEST_TABLE')
90    
91    import aster
92    from Accas import _F
93    from Utilitai.Utmess import  UTMESS
94
95    is_ok = 0
96
97    # vérifier que le fichier a été fermé
98    tinfo__ = INFO_EXEC_ASTER(LISTE_INFO='ETAT_UNITE', FICHIER=FICHIER)
99    if tinfo__['ETAT_UNITE', 1].find('OUVERT') > -1:
100       UTMESS('S','TEST0_2',valk=FICHIER)
101
102    # lecture du fichier
103    if not os.path.isfile(FICHIER):
104       UTMESS('S', 'TEST0_3', valk=FICHIER)
105    fileobj = open(FICHIER, 'r')
106
107    # filtre par expression régulière
108    try:
109       fileobj = regexp_filter(fileobj, kwargs['EXPR_IGNORE'])
110    except TestFichierError, valk:
111       UTMESS('S', 'TEST0_1', valk=valk)
112
113    # calcule le nombre de réels et la somme ou min/max
114    nbval, valeur, chksum = test_iter(fileobj, function=dict_func_test[TYPE_TEST], verbose=(INFO > 1))
115    fileobj.close()
116
117    # produit le TEST_TABLE
118    refsum = VALE_K or 'non testé'
119    is_ok = int(chksum == refsum)
120    tab1__ = CREA_TABLE(LISTE=(_F(PARA='NBVAL',  LISTE_I=nbval,),
121                               _F(PARA='VALEUR', LISTE_R=valeur,),
122                               _F(PARA='TEXTE',  LISTE_I=is_ok),),)
123    if VALE is not None:
124       sVALE = '%20.13e' % VALE
125    else:
126       sVALE = 'non testé'
127    UTMESS('I', 'TEST0_4', vali=(nbval, NB_VALE), valr=valeur, valk=(chksum, refsum, FICHIER, sVALE))
128    
129    kwopt = { 'REFERENCE' : kwargs['REFERENCE'], }
130    if kwargs['REFERENCE'] == 'NON_REGRESSION':
131       kwopt['VERSION'] = kwargs['VERSION']
132    
133    TEST_TABLE(TABLE=tab1__,
134               NOM_PARA='NBVAL',
135               VALE_I=NB_VALE,
136               CRITERE='ABSOLU',
137               PRECISION=0,
138               **kwopt)
139
140    if VALE:
141       TEST_TABLE(TABLE=tab1__,
142                  NOM_PARA='VALEUR',
143                  VALE=VALE,
144                  CRITERE=CRITERE,
145                  PRECISION=PRECISION,
146                  **kwopt)
147
148    if VALE_K:
149       TEST_TABLE(TABLE=tab1__,
150                  NOM_PARA='TEXTE',
151                  VALE_I=int(True),
152                  PRECISION=0,
153                  CRITERE='ABSOLU',
154                  **kwopt)
155
156    DETRUIRE(CONCEPT=_F(NOM=(tinfo__, tab1__),),
157             ALARME='NON',INFO=1,)
158    return ier
159
160 #-------------------------------------------------------------------------------
161 def regexp_filter(file_in, regexp_ignore, debug=False):
162    """Filtre le fichier fourni (file descriptor) en utilisant les
163    expressions régulières fournies.
164    On retourne l'objet file vers le fichier modifié (ou non).
165    """
166    if not regexp_ignore:      # None or []
167       return file_in
168    # vérification des expressions régulières
169    if type(regexp_ignore) not in (list, tuple):
170       regexp_ignore = [regexp_ignore,]
171    l_regexp = []
172    for exp in regexp_ignore:
173       try:
174          obj = re.compile(exp)
175       except re.error, s:
176          raise TestFichierError, (s, str(exp))
177       else:
178          l_regexp.append(obj)
179    # filtre du fichier
180    file_out = os.tmpfile()
181    file_in.seek(0)
182    for i, line in enumerate(file_in):
183       if debug:
184          print 'LIGNE', i,
185       keep = True
186       for exp in l_regexp:
187          if exp.search(line):
188             keep = False
189             if debug:
190                print ' >>>>>>>>>> IGNOREE <<<<<<<<<<'
191             break
192       if keep:
193          file_out.write(line)
194          if debug:
195             print
196    file_out.seek(0)
197    return file_out
198
199
200 #-------------------------------------------------------------------------------
201 re_float_expo = re.compile('[-+]?[0-9\.]+[eED][\-\+]{0,1}[0-9]+')
202 re_float      = re.compile('[-+]?[0-9]+?\.[0-9]*')
203 re_int        = re.compile('[0-9]+')
204
205 re_fortran    = re.compile('([0-9]+)[dD]([\-\+]{0,1}[0-9]+)')
206
207 #-------------------------------------------------------------------------------
208 def test_iter(obj, function, verbose=False):
209    """
210    Cette fonction compte le nombre de réels dans le fichier et une grandeur
211    à partir des valeurs (somme, sommes des valeurs absolues, min/max...).
212    IN :
213       obj      : objet 'file' ou 'string' sur le lequel on peut itérer
214       function : fonction de test   val = func_test(val, [xi, ...])
215       verbose  : on affiche le résumé si info>0
216    OUT :
217       nombre de valeurs, valeur résultat
218    """
219    max_buff_size = 1000
220    nbval = 0
221    val = 0.
222    hfile = hash_new()
223    
224    # Si on lit tout le fichier d'un coup, on va environ 3 fois plus vite
225    # que si on le lit ligne à ligne, mais on consomme en mémoire environ
226    # 5 fois la taille du fichier...
227    # En lisant par paquet de 1000 (ou 10000), on va quasiment aussi vite
228    # en consommant très peu de mémoire.
229    
230    #    fichier     tout   ligne/ligne   1000 lignes
231    #     10 Mo       3 s      10 s       3 s
232    #     50 Mo      17 s      48 s      17 s
233    #    100 Mo      34 s      96 s      35 s
234    
235    # l'itérateur est l'objet file lui-même ou on le crée sur la liste
236    if type(obj) is file:
237       obj.seek(0)
238       iterator = obj
239    else:
240       iterator = iter(obj)
241    
242    ok = True
243    buff = []
244    while ok:
245       try:
246          text = iterator.next()
247       except StopIteration:
248          ok = False
249          text = ''
250       buff.append(text)
251       if ok and len(buff) < max_buff_size:
252          continue
253       else:
254          text = ''.join(buff)
255          buff = []
256
257       l_float = re_float_expo.findall(text)
258       l_float = [s.replace('D', 'E') for s in l_float]
259       text =    re_float_expo.sub('', text)
260       l_float.extend(re_float.findall(text))
261       text =         re_float.sub('', text)
262       l_float.extend(  re_int.findall(text))
263       text =           re_int.sub('', text)
264       
265       nbval += len(l_float)
266       val    = function(val, l_float)
267
268       text = ''.join([s.strip() for s in text.split()])
269       hfile.update(text)
270       
271       if verbose:
272          print 'Nombres réels et entiers :'
273          print l_float
274          print 'Texte :'
275          print text
276    
277    chksum = hfile.hexdigest()
278    
279    return nbval, val, chksum
280
281 #-------------------------------------------------------------------------------
282 def test_file(filename, regexp_ignore=[], type_test='SOMM', verbose=False):
283    """Raccourci pour tester rapidement un fichier (utilisé par stanley.py).
284    """
285    if type(regexp_ignore) not in (list, tuple):
286       regexp_ignore = [regexp_ignore,]
287
288    fileobj = open(filename, 'r')
289    fileobj = regexp_filter(fileobj, regexp_ignore)
290
291    nbv, val, chksum = test_iter(fileobj, function=dict_func_test[type_test], verbose=verbose)
292
293    return nbv, val, chksum
294
295 #-------------------------------------------------------------------------------
296 if __name__ == '__main__':
297    from optparse import OptionParser, OptionGroup
298
299    p = OptionParser(usage='usage: %s fichier [options]' % sys.argv[0])
300    p.add_option('--type_test',
301       action='store', dest='type_test', default='SOMM',
302       help='type du test : SOMM, SOMM_ABS, MIN, MAX')
303    p.add_option('--expr_ignore',
304       action='store', dest='exp', type='string',
305       help='expression régulière à ignorer')
306    p.add_option('-v', '--verbose',
307       action='store_true', dest='verbose', default=False,
308       help='mode bavard')
309    opts, args = p.parse_args()
310
311    if len(args) == 0:
312       p.error('fichier à tester ?')
313
314    if opts.exp is None:
315       exp = []
316    else:
317       exp = [opts.exp]
318
319    fileobj = open(args[0], 'r')
320    fileobj = regexp_filter(fileobj, exp)
321    nbv2, sumv2, chksum2 = test_iter(fileobj, function=dict_func_test[opts.type_test], verbose=opts.verbose)
322    print '%6d valeurs, resultat = %f, texte : %s' % (nbv2, sumv2, chksum2)
323
324