"""Automatic verification that the ANUGA fitting code is not taking more time
or memory than usual.  This test has been tailored for computers in GA.

I'm leaving a 20% error margin

Note, going from version 4897 to 4917 uses more memory, based on how
memory is measured here. What is actually happening is the mesh
generation is using less memory, in version 4917.  In version 4897
mesh gen uses and frees up more memory, so python asks for less extra
memory in the fitting stage.  So overall version 4917 is an
improvement.

RAW DATA
 version 4897
test_fit_time_and_mem (__main__.Test_uq) ...  very start mem_usage() 98108
 before fitting mem_usage() 134696
 after fitting mem_usage() 155820

version 4917
test_fit_time_and_mem (__main__.Test_uq) ...  very start mem_usage() 98076
 before fitting mem_usage() 120012
 after fitting mem_usage() 150212
time 15.19490695
mem 30200

2009 June 22 - RW
Changed the time/memory values to be exactly those found on the hardware.
Took 10 measurements, used maximum in found values.

"""

import unittest
import os, sys

from anuga.fit_interpolate.benchmark_least_squares import BenchmarkLeastSquares

class Test_uq(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    # FIXME test the time to put .pts elevation into a domain object
    # FIXME do tests for interpolate as well.

    # A version round 4872 has slower times.
    # That's because v4872 is using geo-ref, whereas the
    # previous version did not.

    def test_fit_time_and_mem(self):
        import socket

        # get hostname - for *nix and Windows
        host =  socket.gethostname()

        # define dictionary of expected time/memory usage per machine.
        # key must be unique *prefix* of machine name, lowercase.
        # value is tuple: (time, memory) in seconds and KiB.
        expected_results = {'tornado':  (10.8, 40468),  # tornado headnode
                            'cyclone':  (7.4,  40468),  # cyclone headnode
                            'compute':  (10.8, 40468),  # cluster computenode
                            'nautilus': (8.1,  16104),  # Ole's 32bit Ubuntu
                            'bogong':   (14.2, 30000),  # ANU?
                            'pc-31569': (31.6, 15000),  # DSG's PC?
                            'pc-32572': (12.8, 15788),  # Ross' 32bit work Ubuntu
                            'saturn':   (12.8, 39404)   # Ross' 64bit home Ubuntu
                           } 

        # run trial, report on time and memory
        ben = BenchmarkLeastSquares()
        (time, mem, num_tri, one_t,
         more_t, quad_t) = ben.trial(num_of_points=1000,
                                     maxArea=0.0001,
                                     is_fit=True,
                                     segments_in_mesh=False,
                                     use_file_type='pts',
                                     save=False
                                    )

        # Get expected machine values, else a default set of values
        time_standard = 15.0        # max of above, plus a little
        mem_standard = 40000
        for key in expected_results:
            if host.lower().startswith(key):
                (time_standard, mem_standard) = expected_results[key]
                break

        # don't want exception here, report on time *and* memory
        got_error = False
        msg = ('Time used was %.1f s, standard is %.1f s +20%% (%.1f s)'
               % (time, time_standard, int(time_standard*1.2)))
        #print msg
        #assert time < time_standard*1.2, msg
        if time > time_standard*1.2:
            print msg
            got_error = True

        if sys.platform == 'win32':
            # Memory usage does not work on windows
            return
        
        # Before change: https://datamining.anu.edu.au/anuga/changeset/5855
        # which closed tickets 244 and 302, mem_standard was as above.
        # Temporary until ticket:242 is fixed increase it by 25%
        #mem_standard *= 1.25
        # Ticket:242 is now fixed (19 Jan 2009), so mem_standard is 
        #reduced again

        msg = ('Memory used was %d KiB, standard is %d KiB +20%% (%d KiB)'
               % (mem, mem_standard, int(mem_standard*1.2)))
        #print msg
        assert mem < mem_standard*1.2, msg            

        if got_error:
            raise RuntimeError
            
#-------------------------------------------------------------
if __name__ == "__main__":
    suite = unittest.makeSuite(Test_uq,'test')
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)
