Changeset 6660


Ignore:
Timestamp:
Mar 31, 2009, 9:14:03 AM (15 years ago)
Author:
rwilson
Message:

Reformat code, document, add full logging.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • anuga_validation/automated_validation_tests/patong_validation/validate_patong.py

    r6649 r6660  
    11'''
    2 Automatic verification that the ANUGA code validates against the patong
    3 dataset as expected.
     2Automatic verification that the ANUGA code runs the Patong simulation
     3and produces the expected output.
    44
    55Required files are downloaded from the ANUGA servers if they are
     
    1010import glob
    1111import unittest
    12 #import logging
    1312import time
     13import shutil
     14
    1415import project
    1516from anuga.utilities.system_tools import get_web_file, untar_file
     
    1718
    1819
     20# base URL for the remote ANUGA data
     21PATONG_DATA_URL = 'http://10.7.64.243/patong_validation_data/'
     22
    1923# path to the local data directory
    2024Local_Data_Directory = os.path.join('.', 'local_data')
     
    2428
    2529# sequence of required local data objects
    26 Local_Data_Objects = ('patong.sww', 'anuga')
    27 
    28 # base URL for the remote ANUGA data
    29 ANUGA_URL = 'http://10.7.64.243/patong_validation_data/'
     30# first is always the SWW file to be compared
     31Local_Data_Objects = ('patong.sww', 'data')
     32
     33# name of stdout catch file for runmodel.py
     34RUNMODEL_STDOUT = 'runmodel.stdout'
     35
     36# text at start of 'output dir' line in RUNMODEL_STDOUT file
     37OUTDIR_PREFIX = 'Make directory '
     38
     39# Name of SWW file produced by simulation
     40OUTPUT_SWW = 'patong.sww'
     41
     42
     43def setup():
     44    '''Prepare for the validation run.
     45
     46    Check we have required data set in project.py.
     47    '''
     48   
     49    # Check that environment variables are defined.
     50    if os.getenv(project.ENV_INUNDATIONHOME) is None:
     51        msg = ("Environment variable '%s' is not set in project.py"
     52               % project.ENV_INUNDATIONHOME)
     53        raise Exception, msg
     54
     55    if os.getenv(project.ENV_MUXHOME) is None:
     56        msg = ("Environment variable '%s' is not set in project.py"
     57               % project.ENV_MUXHOME)
     58        raise Exception, msg
     59
    3060
    3161def update_local_data():
    32     # update one data object
     62    '''Update local data objects from the server.
     63
     64    These are expected to be *.tgz files/directories.
     65    '''
     66   
     67    # local function to update one data object
    3368    def update_object(obj, auth):
     69        '''Update object 'obj' using authentication tuple 'auth'.'''
     70       
    3471        # Get a unique date+time string to defeat caching.  The idea is to add
    3572        # this to the end of any URL so proxy sees a different request.
     
    4481        local_digest = local_file + '.digest'
    4582       
    46         object_url = ANUGA_URL + obj + '.tgz'
     83        object_url = PATONG_DATA_URL + obj + '.tgz'
    4784        digest_url = object_url + '.digest'
    4885
    49         # see if have both digest and object .tgz
     86        # see if missing either digest or object .tgz
    5087        if not os.path.exists(local_digest) or not os.path.exists(local_file):
    5188            # no digest or no object, download both digest and object
     
    5794        else:
    5895            # download object digest to remote data directory
    59             object_url = ANUGA_URL + obj + '.tgz.digest'
    6096            log.debug('Fetching remote file %s' % object_url)
    61             auth = get_web_file(object_url+cache_defeat,
     97            auth = get_web_file(digest_url+cache_defeat,
    6298                                remote_digest, auth=auth)
    6399           
    64100            # compare remote with local digest
    65101            fd = open(local_digest, 'r')
    66             local_digest_data = fd.read()
     102            local_data_digest = fd.read()
    67103            fd.close()
    68104
    69105            fd = open(remote_digest, 'r')
    70             remote_digest_data = fd.read()
     106            remote_data_digest = fd.read()
    71107            fd.close()
    72108
    73             # if local digest != remote digest, refresh object
    74             if local_digest_data != remote_digest_data:
     109            # if digests differ, refresh object
     110            if local_data_digest != remote_data_digest:
    75111                log.debug('Local file %s is out of date' % obj)
    76112                fd = open(local_digest, 'w')
    77                 fd.write(remote_digest_data)
     113                fd.write(remote_data_digest)
    78114                fd.close()
    79115
    80                 object_url = ANUGA_URL + obj + '.tgz'
    81                 local_file = local_path + '.tgz'
    82116                log.debug('Fetching remote file %s' % object_url)
    83117                auth = get_web_file(object_url+cache_defeat,
     
    85119        return auth
    86120
     121    log.debug('----------------------------------------- refreshing local data')
    87122   
    88123    # create local data directory if required
     
    90125        os.mkdir(Local_Data_Directory)
    91126
    92     # create or clean out remote data copy directory
    93     if not os.path.exists(Remote_Data_Directory):
    94         os.mkdir(Remote_Data_Directory)
    95     rem_files = glob.glob(os.path.join(Remote_Data_Directory, '*'))
    96     for file in rem_files:
    97         os.remove(file)
     127    # clean out remote data copy directory
     128    shutil.rmtree(Remote_Data_Directory, ignore_errors=True)
     129    os.mkdir(Remote_Data_Directory)
    98130
    99131    # refresh local files
     
    108140        untar_file(tar_path, target_dir=Local_Data_Directory)
    109141       
    110 
    111 class Test_Patong(unittest.TestCase):
    112     def setUp(self):
    113         # Check that environment variables are defined.
    114         if os.getenv(project.ENV_INUNDATIONHOME) is None:
    115             msg = ("Environment variable '%s' is not set in project.py"
    116                    % project.ENV_INUNDATIONHOME)
    117             raise Exception, msg
    118 
    119         if os.getenv(project.ENV_MUXHOME) is None:
    120             msg = ("Environment variable '%s' is not set in project.py"
    121                    % project.ENV_MUXHOME)
    122             raise Exception, msg
    123 
    124     def tearDown(self):
    125         pass
    126 ##        # clear all data objects from local data directory
    127 ##        for data_object in Local_Data_Objects:
    128 ##            try:
    129 ##                log.debug('Deleting %s' % os.path.join(Local_Data_Directory,
    130 ##                                                       data_object))
    131 ##                os.remove(os.path.join(Local_Data_Directory, data_object))
    132 ##            except IOError:
    133 ##                pass
    134 
    135     def test_that_output_is_as_expected(self):
    136         # make sure local data is up to date
    137         update_local_data()
    138         print 'update done'
    139 
    140         # modify environment so we use the local data
    141         # INUNDATIONHOME points into the 'anuga' local data directory
    142         # N:\georisk_models\inundation\data\thailand\patong_tsunami_scenario\anuga
    143         old_inundationhome = os.getenv(project.ENV_INUNDATIONHOME)
    144         os.putenv(project.ENV_INUNDATIONHOME,
    145                   os.path.join(Local_Data_Directory, 'anuga'))
    146         # MUXHOME isn't used, but must exist
    147         undo_muxhome = False
    148         if os.getenv(project.ENV_MUXHOME) is None:
    149             os.putenv(project.ENV_MUXHOME,
    150                       os.path.join(Local_Data_Directory, 'data'))
    151             undo_muxhome = True
    152        
    153         # run the simulation, produce SWW file
    154         s = 'run_model.py'
    155         cmd = 'python %s > %s.stdout' % (s, s)
    156         print 'cmd=%s' % cmd
    157         res = os.system(cmd)
    158         print 'res=%s' % str(res)
    159         assert res == 0
    160 
    161         # is SWW file as expected?
    162         print 'About to run compare_output_with_expected.py'
    163         s = 'compare_output_with_expected.py'
    164         res = os.system('python %s > %s.stdout'
    165                         % (s, s))
    166         print 'Result from %s is %d' % (s, res)
    167         assert res == 0
    168 
    169         # undo environment changes
    170         if old_inundationhome:
    171             os.putenv(project.ENV_INUNDATIONHOME, old_inundationhome)
    172         if undo_muxhome:
    173             os.putenv(project.ENV_MUXHOME, None)
     142    log.debug('Update done.')
     143    log.debug('----------------------------------------- refreshing local data')
     144
     145
     146def run_simulation():
     147    '''Run the Patong simulation.'''
     148   
     149    # modify environment so we use the local data
     150    # INUNDATIONHOME points into the 'data' local data directory
     151    old_inundationhome = os.getenv(project.ENV_INUNDATIONHOME)
     152    os.putenv(project.ENV_INUNDATIONHOME,
     153              os.path.join(Local_Data_Directory, ''))
     154    old_muxhome = os.getenv(project.ENV_MUXHOME)
     155    os.putenv(project.ENV_MUXHOME,
     156              os.path.join(Local_Data_Directory, 'data'))
     157   
     158    # run the simulation, produce SWW file
     159    log.debug('Running Patong simulation ...')
     160    cmd = 'python run_model.py > %s' % RUNMODEL_STDOUT
     161    res = os.system(cmd)
     162    assert res == 0
     163
     164    # undo environment changes
     165    if old_inundationhome:
     166        os.putenv(project.ENV_INUNDATIONHOME, old_inundationhome)
     167    if old_muxhome:
     168        os.putenv(project.ENV_MUXHOME, old_muxhome)
     169
     170   
     171def check_that_output_is_as_expected():
     172    '''Check that validation output is as required.'''
     173
     174    # get path to expected SWW file
     175    log.debug('Checking that simulation results are as expected ...')
     176    local_sww = os.path.join(Local_Data_Directory, Local_Data_Objects[0])
     177
     178    # get output directory from stdout capture file
     179    try:
     180        fd = open(RUNMODEL_STDOUT, 'r')
     181    except IOError, e:
     182        log.critical("Can't open catch file '%s': %s"
     183                     % (RUNMODEL_STDOUT, str(e)))
     184        return 1
     185    lines = fd.readlines()
     186    fd.close
     187
     188    output_directory = None
     189    for line in lines:
     190        if line.startswith(OUTDIR_PREFIX):
     191            output_directory = line.replace(OUTDIR_PREFIX, '', 1)
     192            output_directory = output_directory.strip('\n')
     193            break
     194    if output_directory is None:
     195        log.critical("Couldn't find line starting with '%s' in file '%s'"
     196                     % (OUTDIR_PREFIX, RUNMODEL_STDOUT))
     197        return 1
     198
     199    # compare SWW files here and there
     200    new_output_sww = os.path.join(output_directory, OUTPUT_SWW)
     201    cmd = 'python cmpsww.py %s %s > cmpsww.stdout' % (local_sww, new_output_sww)
     202    res = os.system(cmd)
     203    assert res == 0
     204    log.debug('Simulation results are as expected.')
     205
     206
     207def teardown():
     208    '''Clean up after validation run.'''
     209   
     210    # clear all data objects from local data directory
     211    for data_object in Local_Data_Objects:
     212        obj_path = os.path.join(Remote_Data_Directory, data_object)
     213        shutil.rmtree(obj_path, ignore_errors=True)
     214           
    174215
    175216################################################################################
    176 
    177 if __name__ == "__main__":
    178     # set logging levels
    179     #log.console_logging_level = log.CRITICAL   # no console logging
    180     log.console_logging_level = log.DEBUG
    181 
    182     suite = unittest.makeSuite(Test_Patong, 'test')
    183     runner = unittest.TextTestRunner(verbosity=2)
    184     runner.run(suite)
     217# Mainline - run the simulation, check output.
     218################################################################################
     219
     220# set logging levels
     221log.console_logging_level = log.DEBUG
     222setup()
     223
     224# make sure local data is up to date
     225update_local_data()
     226
     227# run the simulation
     228##import cProfile
     229##cProfile.run('run_simulation()', filename='patong.prof')
     230
     231run_simulation()
     232
     233# check output is as expected
     234check_that_output_is_as_expected()
     235
     236# clean up
     237teardown()
Note: See TracChangeset for help on using the changeset viewer.