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