~maddevelopers/mg5amcnlo/2.9.4

« back to all changes in this revision

Viewing changes to tests/IOTests.py

pass to v2.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
################################################################################
 
2
#
 
3
# Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors
 
4
#
 
5
# This file is a part of the MadGraph5_aMC@NLO project, an application which 
 
6
# automatically generates Feynman diagrams and matrix elements for arbitrary
 
7
# high-energy processes in the Standard Model and beyond.
 
8
#
 
9
# It is subject to the MadGraph5_aMC@NLO license which should accompany this 
 
10
# distribution.
 
11
#
 
12
# For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch
 
13
#
 
14
################################################################################
 
15
 
 
16
import copy
 
17
import os
 
18
import sys
 
19
import shutil
 
20
import re
 
21
import glob
 
22
import tarfile
 
23
import datetime
 
24
import unittest
 
25
import subprocess
 
26
import pydoc
 
27
 
 
28
root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
 
29
sys.path.append(root_path)
 
30
 
 
31
import madgraph.various.misc as misc
 
32
 
 
33
from madgraph.interface.extended_cmd import Cmd
 
34
 
 
35
from madgraph.iolibs.files import cp, ln, mv
 
36
from madgraph import MadGraph5Error
 
37
 
 
38
pjoin = os.path.join
 
39
path = os.path
 
40
 
 
41
_file_path = os.path.dirname(os.path.realpath(__file__))
 
42
_input_file_path = path.abspath(os.path.join(_file_path,'input_files'))
 
43
_hc_comparison_files = pjoin(_input_file_path,'IOTestsComparison')
 
44
_hc_comparison_tarball = pjoin(_input_file_path,'IOTestsComparison.tar.bz2')
 
45
 
 
46
class IOTest(object):
 
47
    """ IOTest runner and attribute container. It can be overloaded depending on
 
48
    what kind of IO test will be necessary later """
 
49
 
 
50
    # Handy definitions
 
51
    proc_files = ['[^.+\.(f|dat|inc)$]']
 
52
    # Some model files are veto because they are sourced by dictionaries whose 
 
53
    # order is random.
 
54
    model_files = ['../../Source/MODEL/[^.+\.(f|inc)$]',
 
55
                   '-../../Source/MODEL/lha_read.f',
 
56
                   '-../../Source/MODEL/param_read.inc',
 
57
                   '-../../Source/MODEL/param_write.inc']            
 
58
    helas_files = ['../../Source/DHELAS/[^.+\.(f|inc)$]']
 
59
    
 
60
    # We also exclude the helas_files because they are sourced from unordered
 
61
    # dictionaries.
 
62
    all_files = proc_files+model_files
 
63
 
 
64
    def __init__(self, hel_amp=None,
 
65
                       exporter=None,
 
66
                       helasModel=None,
 
67
                       testedFiles=None,
 
68
                       outputPath=None):
 
69
        """ Can be overloaded to add more options if necessary.
 
70
        The format above is typically useful because we don't aim at
 
71
        testing all processes for all exporters and all model, but we 
 
72
        choose certain combinations which spans most possibilities.
 
73
        Notice that the process and model can anyway be recovered from the 
 
74
        LoopAmplitude object, so it does not have to be specified here."""
 
75
 
 
76
        if testedFiles is None:
 
77
            raise MadGraph5Error, "TestedFiles must be specified in IOTest."
 
78
        
 
79
        if outputPath is None:
 
80
            raise MadGraph5Error, "outputPath must be specified in IOTest."
 
81
        
 
82
        self.testedFiles = testedFiles
 
83
        self.hel_amp = hel_amp 
 
84
        self.helasModel = helasModel
 
85
        self.exporter = exporter
 
86
        # Security mesure
 
87
        if not str(path.dirname(_file_path)) in str(outputPath) and \
 
88
                                        not str(outputPath).startswith('/tmp/'):
 
89
            raise MadGraph5Error, "OutputPath must be within MG directory or"+\
 
90
                                                                     " in /tmp/"            
 
91
        else:
 
92
            self.outputPath = outputPath
 
93
    
 
94
    def run(self):
 
95
        """ Run the test and returns the path where the files have been 
 
96
        produced and relative to which the paths in TestedFiles are specified. """
 
97
        
 
98
        self.clean_output()
 
99
        model = self.hel_amp.get('processes')[0].get('model')
 
100
        self.exporter.copy_v4template(model.get('name'))
 
101
        self.exporter.generate_loop_subprocess(self.hel_amp, self.helasModel)
 
102
        wanted_lorentz = self.hel_amp.get_used_lorentz()
 
103
        wanted_couplings = list(set(sum(self.hel_amp.get_used_couplings(),[])))
 
104
        self.exporter.convert_model_to_mg4(model,wanted_lorentz,wanted_couplings)
 
105
            
 
106
        proc_name='P'+self.hel_amp.get('processes')[0].shell_string()
 
107
        return pjoin(self.outputPath,'SubProcesses',proc_name)
 
108
    
 
109
    def clean_output(self):
 
110
        """ Remove the output_path if existing. Careful!"""
 
111
        if not str(path.dirname(_file_path)) in str(self.outputPath) and \
 
112
                                   not str(self.outputPath).startswith('/tmp/'):
 
113
            raise MadGraph5Error, "Cannot safely remove %s."%str(self.outputPath)
 
114
        else:
 
115
            if path.isdir(self.outputPath):
 
116
                shutil.rmtree(self.outputPath)
 
117
 
 
118
#===============================================================================
 
119
# IOTestManager
 
120
#===============================================================================
 
121
class IOTestManager(unittest.TestCase):
 
122
    """ A helper class to perform tests based on the comparison of files output 
 
123
    by exporters against hardcoded ones. """
 
124
    
 
125
    # Define a bunch of paths useful
 
126
    _input_file_path = path.abspath(os.path.join(_file_path,'input_files'))
 
127
    _mgme_file_path = path.abspath(os.path.join(_file_path, *([os.path.pardir]*1)))
 
128
    _loop_file_path = pjoin(_mgme_file_path,'Template','loop_material')
 
129
    _cuttools_file_path = pjoin(_mgme_file_path, 'vendor','CutTools')
 
130
    _hc_comparison_files = pjoin(_input_file_path,'IOTestsComparison')
 
131
 
 
132
    # The tests loaded are stored here
 
133
    # Each test is stored in a dictionary with entries of the format:
 
134
    # {(folder_name, test_name) : IOTest}      
 
135
    all_tests = {}
 
136
    
 
137
    # filesChecked_filter allows to filter files which are checked.
 
138
    # These filenames should be the path relative to the
 
139
    # position SubProcess/<P0_proc_name>/ in the output. Notice that you can
 
140
    # use the parent directory keyword ".." and instead of the filename you
 
141
    # can exploit the syntax [regexp] (brackets not part of the regexp)
 
142
    # Ex. ['../../Source/DHELAS/[.+\.(inc|f)]']
 
143
    # You can also prepend '-' to a filename to veto it (it cannot be a regexp
 
144
    # in this case though.)
 
145
    filesChecked_filter = ['ALL']
 
146
    # To filter what tests you want to use, edit the tag ['ALL'] by the
 
147
    # list of test folders and names you want in.
 
148
    # You can prepend '-' to the folder or test name to veto it instead of
 
149
    # selecting it. Typically, ['-longTest'] considers all tests but the
 
150
    # longTest one (synthax not available for filenames)
 
151
    testFolders_filter = ['ALL']
 
152
    testNames_filter = ['ALL'] 
 
153
    
 
154
    def __init__(self,*args,**opts):
 
155
        """ Add the object attribute my_local_tests."""
 
156
        # Lists the keys for the tests of this particular instance
 
157
        self.instance_tests = []
 
158
        super(IOTestManager,self).__init__(*args,**opts)    
 
159
    
 
160
    def runTest(self,*args,**opts):
 
161
        """ This method is added so that one can instantiate this class """
 
162
        raise MadGraph5Error, 'runTest in IOTestManager not supposed to be called.'
 
163
    
 
164
    def assertFileContains(self, source, solution):
 
165
        """ Check the content of a file """
 
166
        list_cur=source.read().split('\n')
 
167
        list_sol=solution.split('\n')
 
168
        while 1:
 
169
            if '' in list_sol:
 
170
                list_sol.remove('')
 
171
            else:
 
172
                break
 
173
        while 1:
 
174
            if '' in list_cur:
 
175
                list_cur.remove('')
 
176
            else:
 
177
                break            
 
178
        for a, b in zip(list_sol, list_cur):
 
179
            self.assertEqual(a,b)
 
180
        self.assertEqual(len(list_sol), len(list_cur))
 
181
 
 
182
    @classmethod
 
183
    def need(cls,folderName=None, testName=None):
 
184
        """ Returns True if the selected filters do not exclude the testName
 
185
        and folderName given in argument. Specify None to disregard the filters
 
186
        corresponding to this category."""
 
187
        
 
188
        if testName is None and folderName is None:
 
189
            return True
 
190
        
 
191
        if not testName is None:
 
192
            pattern = [f[1:] for f in cls.testNames_filter if f.startswith('+')]
 
193
            chosen = [f for f in cls.testNames_filter if \
 
194
                            not f.startswith('-') and not f.startswith('+')]
 
195
            veto = [f[1:] for f in cls.testNames_filter if f.startswith('-')]
 
196
            if testName in veto:
 
197
                return False
 
198
            if chosen!=['ALL'] and not testName in chosen:
 
199
                if not any(testName.startswith(pat) for pat in pattern):
 
200
                    return False
 
201
 
 
202
        if not folderName is None:
 
203
            pattern = [f[1:] for f in cls.testFolders_filter if f.startswith('+')]
 
204
            chosen = [f for f in cls.testFolders_filter if \
 
205
                            not f.startswith('-') and not f.startswith('+')]
 
206
            veto = [f[1:] for f in cls.testFolders_filter if f.startswith('-')]
 
207
            if folderName in veto:
 
208
                return False
 
209
            if chosen!=['ALL'] and not folderName in chosen:
 
210
                if not any(folderName.startswith(pat) for pat in pattern):
 
211
                    return False
 
212
        
 
213
        if not folderName is None and not testName is None:
 
214
            if (folderName,testName) in cls.all_tests.keys() and \
 
215
               (folderName,testName) in cls.instance_tests:
 
216
                return False
 
217
 
 
218
        return True
 
219
 
 
220
    @classmethod
 
221
    def toFileName(cls, file_path):
 
222
        """ transforms a file specification like ../../Source/MODEL/myfile to
 
223
        %..%..%Source%MODEL%myfile """
 
224
        fpath = copy.copy(file_path)
 
225
        if not isinstance(fpath, str):
 
226
            fpath=str(fpath)
 
227
        if '/' not in fpath:
 
228
            return fpath
 
229
        
 
230
        return '%'+'%'.join(file_path.split('/'))
 
231
 
 
232
    @classmethod        
 
233
    def toFilePath(cls, file_name):
 
234
        """ transforms a file name specification like %..%..%Source%MODEL%myfile
 
235
        to ../../Source/MODEL/myfile"""
 
236
        
 
237
        if not file_name.startswith('%'):
 
238
            return file_name
 
239
        
 
240
        return pjoin(file_name[1:].split('%'))
 
241
    
 
242
    def test_IOTests(self):
 
243
        """ A test function in the mother so that all childs automatically run
 
244
        their tests when scanned with the test_manager. """
 
245
        
 
246
        # Set it to True if you want info during the regular test_manager.py runs
 
247
        self.runIOTests(verbose=False)
 
248
    
 
249
    def addIOTest(self, folderName, testName, IOtest):
 
250
        """ Add the test (folderName, testName) to class attribute all_tests. """
 
251
        
 
252
        if not self.need(testName=testName, folderName=folderName):
 
253
            return
 
254
 
 
255
        # Add this to the instance test_list
 
256
        if (folderName, testName) not in self.instance_tests:
 
257
            self.instance_tests.append((folderName, testName))
 
258
            
 
259
        # Add this to the global test_list            
 
260
        if (folderName, testName) in self.all_tests.keys() and \
 
261
                                  self.all_tests[(folderName, testName)]!=IOtest:
 
262
            raise MadGraph5Error, \
 
263
                          "Test (%s,%s) already defined."%(folderName, testName)
 
264
        else:
 
265
            self.all_tests[(folderName, testName)] = IOtest
 
266
 
 
267
    def runIOTests(self, update = False, force = 0, verbose=False, \
 
268
                                                       testKeys='instanceList'):
 
269
        """ Run the IOTests for this instance (defined in self.instance_tests)
 
270
            and compare the files of the chosen tests against the hardcoded ones
 
271
            stored in tests/input_files/IOTestsComparison. If you see
 
272
            an error in the comparison and you are sure that the newest output
 
273
            is correct (i.e. you understand that this modification is meant to
 
274
            be so). Then feel free to automatically regenerate this file with
 
275
            the newest version by doing 
 
276
            
 
277
              ./test_manager -i U folderName/testName/fileName
 
278
                
 
279
            If update is True (meant to be used by __main__ only) then
 
280
            it will create/update/remove the files instead of testing them.
 
281
            The argument tests can be a list of tuple-keys describing the tests
 
282
            to cover. Otherwise it is the instance_test list.
 
283
            The force argument must be 10 if you do not want to monitor the 
 
284
            modifications on the updated files. If it is 0 you will monitor
 
285
            all modified file and if 1 you will monitor each modified file of
 
286
            a given name only once.
 
287
        """
 
288
        
 
289
        # First make sure that the tarball need not be untarred
 
290
        # Extract the tarball for hardcoded in all cases to make sure the 
 
291
        # IOTestComparison folder is synchronized with it.
 
292
        if path.isdir(_hc_comparison_files):
 
293
            try:
 
294
                shutil.rmtree(_hc_comparison_files)
 
295
            except IOError:
 
296
                pass
 
297
        if path.isfile(_hc_comparison_tarball):
 
298
            tar = tarfile.open(_hc_comparison_tarball,mode='r:bz2')
 
299
            tar.extractall(path.dirname(_hc_comparison_files))
 
300
            tar.close()
 
301
        else:
 
302
            raise MadGraph5Error, \
 
303
          "Could not find the comparison tarball %s."%_hc_comparison_tarball
 
304
 
 
305
        # In update = True mode, we keep track of the modification to 
 
306
        # provide summary information
 
307
        modifications={'updated':[],'created':[], 'removed':[]}
 
308
        
 
309
        # List all the names of the files for which modifications have been
 
310
        # reviewed at least once.The approach taken here is different than
 
311
        # with the list refusedFolder and refusedTest.
 
312
        # The key of the dictionary are the filenames and the value are string
 
313
        # determining the user answer for that file.
 
314
        reviewed_file_names = {}
 
315
        
 
316
        # Chose what test to cover
 
317
        if testKeys == 'instanceList':
 
318
            testKeys = self.instance_tests
 
319
        
 
320
        if verbose: print "\n== Operational mode : file %s ==\n"%\
 
321
                                           ('UPDATE' if update else 'TESTING')
 
322
        for (folder_name, test_name) in testKeys:
 
323
            try:
 
324
                iotest=self.all_tests[(folder_name, test_name)]
 
325
            except KeyError:
 
326
                raise MadGraph5Error, 'Test (%s,%s) could not be found.'\
 
327
                                                       %(folder_name, test_name)
 
328
            if verbose: print "Processing %s in %s"%(test_name,folder_name)
 
329
            files_path = iotest.run()
 
330
 
 
331
            # First create the list of files to check as the user might be using
 
332
            # regular expressions.
 
333
            filesToCheck=[]
 
334
            # Store here the files reckognized as veto rules (with filename
 
335
            # starting with '-')
 
336
            veto_rules = []
 
337
            for fname in iotest.testedFiles:
 
338
                # Disregard the veto rules
 
339
                if fname.endswith(']'):
 
340
                    split=fname[:-1].split('[')
 
341
                    # folder without the final /
 
342
                    folder=split[0][:-1]
 
343
                    search = re.compile('['.join(split[1:]))
 
344
                    # In filesToCheck, we must remove the files_path/ prepended
 
345
                    filesToCheck += [ f[(len(str(files_path))+1):]
 
346
                           for f in glob.glob(pjoin(files_path,folder,'*')) if \
 
347
                               (not search.match(path.basename(f)) is None and \
 
348
                                      not path.isdir(f) and not path.islink(f))]
 
349
                elif fname.startswith('-'):
 
350
                    veto_rules.append(fname[1:])
 
351
                else:
 
352
                    filesToCheck.append(fname)
 
353
            
 
354
            # Apply the trimming of the veto rules
 
355
            filesToCheck = [f for f in filesToCheck if f not in veto_rules]
 
356
            
 
357
            if update:
 
358
                # Remove files which are no longer used for comparison
 
359
                activeFiles = [self.toFileName(f) for f in filesToCheck]
 
360
                for file in glob.glob(pjoin(_hc_comparison_files,folder_name,\
 
361
                                                                test_name,'*')):
 
362
                    # Ignore the .BackUp files and directories
 
363
                    if path.basename(file).endswith('.BackUp') or\
 
364
                                                               path.isdir(file):
 
365
                        continue
 
366
                    if path.basename(file) not in activeFiles:
 
367
                        if force==0 or (force==1 and \
 
368
                         path.basename(file) not in reviewed_file_names.keys()):
 
369
                            answer = Cmd.timed_input(question=
 
370
"""Obsolete ref. file %s in %s/%s detected, delete it? [y/n] >"""\
 
371
                                    %(path.basename(file),folder_name,test_name)
 
372
                                                                   ,default="y")
 
373
                            reviewed_file_names[path.basename(file)] = answer
 
374
                        elif (force==1 and \
 
375
                             path.basename(file) in reviewed_file_names.keys()):
 
376
                            answer = reviewed_file_names[path.basename(file)]
 
377
                        else:
 
378
                            answer = 'Y'
 
379
                            
 
380
                        if answer not in ['Y','y','']:
 
381
                            if verbose: 
 
382
                                print "    > [ IGNORED ] file deletion "+\
 
383
                          "%s/%s/%s"%(folder_name,test_name,path.basename(file))
 
384
                            continue
 
385
 
 
386
                        os.remove(file)
 
387
                        if verbose: print "    > [ REMOVED ] %s/%s/%s"\
 
388
                                    %(folder_name,test_name,path.basename(file))
 
389
                        modifications['removed'].append(
 
390
                                            '/'.join(str(file).split('/')[-3:]))
 
391
 
 
392
                    
 
393
            # Make sure it is not filtered out by the user-filter
 
394
            if self.filesChecked_filter!=['ALL']:
 
395
                new_filesToCheck = []
 
396
                for file in filesToCheck:
 
397
                    # Try if it matches any filter
 
398
                    for filter in self.filesChecked_filter:
 
399
                        # A regular expression
 
400
                        if filter.endswith(']'):
 
401
                            split=filter[:-1].split('[')
 
402
                            # folder without the final /
 
403
                            folder=split[0][:-1]
 
404
                            if folder!=path.dirname(pjoin(file)):
 
405
                                continue
 
406
                            search = re.compile('['.join(split[1:]))
 
407
                            if not search.match(path.basename(file)) is None:
 
408
                                new_filesToCheck.append(file)
 
409
                                break    
 
410
                        # Just the exact filename
 
411
                        elif filter==file:
 
412
                            new_filesToCheck.append(file)
 
413
                            break
 
414
                filesToCheck = new_filesToCheck
 
415
            
 
416
            # Now we can scan them and process them one at a time
 
417
            # Keep track of the folders and testNames the user did not want to
 
418
            # create
 
419
            refused_Folders = []
 
420
            refused_testNames = []
 
421
            for fname in filesToCheck:
 
422
                file_path = path.abspath(pjoin(files_path,fname))
 
423
                self.assertTrue(path.isfile(file_path),
 
424
                                            'File %s not found.'%str(file_path))
 
425
                comparison_path = pjoin(_hc_comparison_files,\
 
426
                                    folder_name,test_name,self.toFileName(fname))
 
427
                if not update:
 
428
                    if not os.path.isfile(comparison_path):
 
429
                        raise MadGraph5Error, 'The file %s'%str(comparison_path)+\
 
430
                                                              ' does not exist.'
 
431
                    goal = open(comparison_path).read()%misc.get_pkg_info()
 
432
                    if not verbose:
 
433
                        self.assertFileContains(open(file_path), goal)
 
434
                    else:
 
435
                        try:
 
436
                            self.assertFileContains(open(file_path), goal)
 
437
                        except AssertionError:
 
438
                            print "    > %s differs from the reference."%fname
 
439
                            
 
440
                else:                        
 
441
                    if not path.isdir(pjoin(_hc_comparison_files,folder_name)):
 
442
                        if force==0:
 
443
                            if folder_name in refused_Folders:
 
444
                                continue
 
445
                            answer = Cmd.timed_input(question=
 
446
"""New folder %s detected, create it? [y/n] >"""%folder_name
 
447
                                                                   ,default="y")
 
448
                            if answer not in ['Y','y','']:
 
449
                                refused_Folders.append(folder_name)
 
450
                                if verbose: print "    > [ IGNORED ] folder %s"\
 
451
                                                                    %folder_name
 
452
                                continue
 
453
                        if verbose: print "    > [ CREATED ] folder %s"%folder_name
 
454
                        os.makedirs(pjoin(_hc_comparison_files,folder_name))
 
455
                    if not path.isdir(pjoin(_hc_comparison_files,folder_name,
 
456
                                                                    test_name)):
 
457
                        if force==0:
 
458
                            if (folder_name,test_name) in refused_testNames:
 
459
                                continue
 
460
                            answer = Cmd.timed_input(question=
 
461
"""New test %s/%s detected, create it? [y/n] >"""%(folder_name,test_name)
 
462
                                                                   ,default="y")
 
463
                            if answer not in ['Y','y','']:
 
464
                                refused_testNames.append((folder_name,test_name))
 
465
                                if verbose: print "    > [ IGNORED ] test %s/%s"\
 
466
                                                        %(folder_name,test_name)
 
467
                                continue
 
468
                        if verbose: print "    > [ CREATED ] test %s/%s"\
 
469
                                                        %(folder_name,test_name)
 
470
                        os.makedirs(pjoin(_hc_comparison_files,folder_name,
 
471
                                                                    test_name))
 
472
                    # Transform the package information to make it a template
 
473
                    file = open(file_path,'r')
 
474
                    target=file.read()
 
475
                    target = target.replace('MadGraph5_aMC@NLO v. %(version)s, %(date)s'\
 
476
                                                           %misc.get_pkg_info(),
 
477
                                          'MadGraph5_aMC@NLO v. %(version)s, %(date)s')
 
478
                    file.close()
 
479
                    if os.path.isfile(comparison_path):
 
480
                        file = open(comparison_path,'r')
 
481
                        existing = file.read()
 
482
                        file.close()
 
483
                        if existing == target:
 
484
                            continue
 
485
                        else:
 
486
                            # Copying the existing reference as a backup
 
487
                            tmp_path = pjoin(_hc_comparison_files,folder_name,\
 
488
                                        test_name,self.toFileName(fname)+'.tmp')
 
489
                            if os.path.isfile(tmp_path):
 
490
                                os.remove(tmp_path)
 
491
                            file = open(tmp_path,'w')
 
492
                            file.write(target)
 
493
                            file.close()
 
494
                            if force==0 or (force==1 and path.basename(\
 
495
                            comparison_path) not in reviewed_file_names.keys()):
 
496
                                text = \
 
497
"""File %s in test %s/%s differs by the following (reference file first):
 
498
"""%(fname,folder_name,test_name)
 
499
                                text += misc.Popen(['diff',str(comparison_path),
 
500
                                  str(tmp_path)],stdout=subprocess.PIPE).\
 
501
                                                                communicate()[0]
 
502
                                # Remove the last newline
 
503
                                if text[-1]=='\n':
 
504
                                    text=text[:-1]
 
505
                                if (len(text.split('\n'))<15):
 
506
                                    print text
 
507
                                else:
 
508
                                    pydoc.pager(text)
 
509
                                    print "Difference displayed in editor."
 
510
                                answer = Cmd.timed_input(question=
 
511
"""Ref. file %s differs from the new one (see diff. before), update it? [y/n] >"""%fname
 
512
                                                                   ,default="y")
 
513
                                os.remove(tmp_path)
 
514
                                reviewed_file_names[path.basename(\
 
515
                                                      comparison_path)] = answer        
 
516
                            elif (force==1 and path.basename(\
 
517
                                comparison_path) in reviewed_file_names.keys()):
 
518
                                answer = reviewed_file_names[path.basename(\
 
519
                                                               comparison_path)]
 
520
                            else:
 
521
                                answer = 'Y'
 
522
                            if answer not in ['Y','y','']:
 
523
                                if verbose: print "    > [ IGNORED ] %s"%fname
 
524
                                continue
 
525
                            
 
526
                            # Copying the existing reference as a backup
 
527
                            back_up_path = pjoin(_hc_comparison_files,folder_name,\
 
528
                                         test_name,self.toFileName(fname)+'.BackUp')
 
529
                            if os.path.isfile(back_up_path):
 
530
                                os.remove(back_up_path)
 
531
                            cp(comparison_path,back_up_path)
 
532
                            if verbose: print "    > [ UPDATED ] %s"%fname
 
533
                            modifications['updated'].append(
 
534
                                      '/'.join(comparison_path.split('/')[-3:]))
 
535
                    else:
 
536
                        if force==0 or (force==1 and path.basename(\
 
537
                            comparison_path) not in reviewed_file_names.keys()):
 
538
                            answer = Cmd.timed_input(question=
 
539
"""New file %s detected, create it? [y/n] >"""%fname
 
540
                                                                   ,default="y")
 
541
                            reviewed_file_names[path.basename(\
 
542
                                                      comparison_path)] = answer
 
543
                        elif (force==1 and path.basename(\
 
544
                                comparison_path) in reviewed_file_names.keys()):
 
545
                            answer = reviewed_file_names[\
 
546
                                                 path.basename(comparison_path)]
 
547
                        else:
 
548
                            answer = 'Y'
 
549
                        if answer not in ['Y','y','']:
 
550
                            if verbose: print "    > [ IGNORED ] %s"%fname
 
551
                            continue
 
552
                        if verbose: print "    > [ CREATED ] %s"%fname
 
553
                        modifications['created'].append(
 
554
                                      '/'.join(comparison_path.split('/')[-3:]))
 
555
                    file = open(comparison_path,'w')
 
556
                    file.write(target)
 
557
                    file.close()
 
558
 
 
559
            # Clean the iotest output
 
560
            iotest.clean_output()
 
561
 
 
562
        # Monitor the modifications when in creation files mode by returning the
 
563
        # modifications dictionary.
 
564
        if update:
 
565
            return modifications
 
566
        else:
 
567
            return 'test_over'
 
568