Source code for nexus.testing

try:
    import numpy as np
    if np.lib.NumpyVersion(np.__version__) >= '2.0.0b1':
        np.set_printoptions(legacy="1.25")
    numpy_available = True
except:
    numpy_available = False
#end try


def_atol =  0.0
def_rtol = 1e-6


# determine if two floats differ
[docs] def float_diff(v1,v2,atol=def_atol,rtol=def_rtol): return np.abs(v1-v2)>atol+rtol*np.abs(v2)
#end def float_diff # determine if two values differ
[docs] def value_diff(v1,v2,atol=def_atol,rtol=def_rtol,int_as_float=False): diff = False v1_bool = isinstance(v1,(bool,np.bool_)) v2_bool = isinstance(v2,(bool,np.bool_)) v1_int = isinstance(v1,(int,np.int_)) and not v1_bool v2_int = isinstance(v2,(int,np.int_)) and not v2_bool v1_float = isinstance(v1,(float,np.float64)) v2_float = isinstance(v2,(float,np.float64)) v1_str = isinstance(v1,(str,np.bytes_)) v2_str = isinstance(v2,(str,np.bytes_)) if id(v1)==id(v2): None elif int_as_float and (v1_int or v1_float) and (v2_int or v2_float): diff = float_diff(v1,v2,atol=atol,rtol=rtol) elif v1_float and v2_float: diff = float_diff(v1,v2,atol=atol,rtol=rtol) elif v1_int and v2_int: diff = v1!=v2 elif (v1_bool or v1_str) and (v2_bool or v2_str): diff = v1!=v2 elif not isinstance(v1,type(v2)) or not isinstance(v2,type(v1)): diff = True elif isinstance(v1,(list,tuple)): v1 = np.array(v1,dtype=object).ravel() v2 = np.array(v2,dtype=object).ravel() if len(v1)!=len(v2): diff = True else: for vv1,vv2 in zip(v1,v2): diff |= value_diff(vv1,vv2,atol,rtol,int_as_float) #end for #end if elif isinstance(v1,np.ndarray): v1 = v1.ravel() v2 = v2.ravel() if len(v1)!=len(v2): diff = True else: for vv1,vv2 in zip(v1,v2): diff |= value_diff(vv1,vv2,atol,rtol,int_as_float) #end for #end if elif isinstance(v1,dict): k1 = v1.keys() k2 = v2.keys() if set(k1)!=set(k2): diff = True else: for k in k1: diff |= value_diff(v1[k],v2[k],atol,rtol,int_as_float) #end for #end if elif isinstance(v1,set): diff = v1!=v2 elif v1 is None and v2 is None: diff = False elif hasattr(v1,'__len__') and hasattr(v2,'__len__') and len(v1)==0 and len(v2)==0: None else: diff = True # unsupported types #end if return diff
#end def value_diff # determine if two objects differ
[docs] def object_diff(o1,o2,atol=def_atol,rtol=def_rtol,int_as_float=False,full=False,bypass=False): diff1 = dict() diff2 = dict() if not bypass: o1 = o1._serial().__dict__ o2 = o2._serial().__dict__ #end if keys1 = set(o1.keys()) keys2 = set(o2.keys()) ku1 = keys1 - keys2 ku2 = keys2 - keys1 km = keys1 & keys2 for k in ku1: diff1[k] = o1[k] #end for for k in ku2: diff2[k] = o2[k] #end for for k in km: v1 = o1[k] v2 = o2[k] if value_diff(v1,v2,atol,rtol,int_as_float): diff1[k] = v1 diff2[k] = v2 #end if #end for diff = len(diff1)!=0 or len(diff2)!=0 if not full: return diff else: return diff,diff1,diff2
#end if #end def object_diff # determine if two text blocks differ
[docs] def read_text_value(s): v = s try: vi = int(s) except: try: v = float(s) except: pass #end try #end try return v
#end def read_text_value
[docs] def read_text_tokens(t): tokens = [] for v in t.split(): tokens.append(read_text_value(v)) #end for return tokens
#end def read_text_tokens
[docs] def text_diff(t1,t2,atol=def_atol,rtol=def_rtol,int_as_float=False,full=False,by_line=False): t1 = t1.replace(',',' , ') t2 = t2.replace(',',' , ') tokens1 = read_text_tokens(t1) tokens2 = read_text_tokens(t2) diff = value_diff(tokens1,tokens2,atol,rtol,int_as_float) if not full: return diff elif not by_line: diff1 = dict() diff2 = dict() nmin = min(len(tokens1),len(tokens2)) for n,(v1,v2) in enumerate(zip(tokens1[:nmin],tokens2[:nmin])): if value_diff(v1,v2,atol,rtol,int_as_float): diff1[n] = v1 diff2[n] = v2 #end if #end for if len(tokens1)>len(tokens2): for n,v in enumerate(tokens1[nmin:]): diff1[nmin+n] = v diff2[nmin+n] = None #end for elif len(tokens2)>len(tokens1): for n,v in enumerate(tokens2[nmin:]): diff1[nmin+n] = None diff2[nmin+n] = v #end for #end if return diff,diff1,diff2 else: diff1 = dict() diff2 = dict() lines1 = t1.splitlines() lines2 = t2.splitlines() nmin = min(len(lines1),len(lines2)) for n,(l1,l2) in enumerate(zip(lines1[:nmin],lines2[:nmin])): tokens1 = read_text_tokens(l1) tokens2 = read_text_tokens(l2) if value_diff(tokens1,tokens2,atol,rtol,int_as_float): diff1[n] = l1 diff2[n] = l2 #end if #end for if len(lines1)>len(lines2): for n,l in enumerate(lines1[nmin:]): diff1[nmin+n] = l diff2[nmin+n] = None #end for elif len(lines2)>len(lines1): for n,l in enumerate(lines2[nmin:]): diff1[nmin+n] = None diff2[nmin+n] = l #end for #end if return diff,diff1,diff2
#end if #end def text_diff # print the difference between two objects #end def print_diff # check for value equality and if different, print the difference
[docs] def check_value_eq(v1,v2,**kwargs): verbose = kwargs.pop('verbose',False) same = value_eq(v1,v2,**kwargs) if not same and (verbose or global_data['verbose']): print('\nValues differ, please see below for details') hline = '========== {} ==========' print() print(hline.format('left value')) print(v1) print() print(hline.format('right value')) print(v2) print() #end if return same
#end def check_value_eq # check for object equality and if different, print the difference
[docs] def check_object_eq(o1,o2,**kwargs): verbose = kwargs.pop('verbose',False) same = object_eq(o1,o2,**kwargs) if not same and (verbose or global_data['verbose']): print('\nObjects differ, please see below for details') print_diff(o1,o2) #end if return same
#end def check_object_eq # additional convenience functions to use value_diff and object_diff value_neq = value_diff
[docs] def value_eq(*args,**kwargs): return not value_neq(*args,**kwargs)
#end def value_eq object_neq = object_diff
[docs] def object_eq(*args,**kwargs): return not object_neq(*args,**kwargs)
#end def object_eq text_neq = text_diff
[docs] def text_eq(*args,**kwargs): return not text_neq(*args,**kwargs)
#end def text_eq # declare test failure # useful inside try/except blocks
[docs] def failed(msg='Test failed.'): assert False,msg
#end def failed
[docs] class FailedTest(Exception): None
#end class FailedTest global_data = dict( verbose = False, job_ref_table = False, )
[docs] def clear_all_sims(): from .simulation import Simulation Simulation.clear_all_sims()
#end def clear_all_sims
[docs] def check_final_state(): from .nexus_base import nexus_core,nexus_core_defaults from .nexus_base import nexus_noncore,nexus_noncore_defaults from .nexus_base import nexus_core_noncore,nexus_core_noncore_defaults assert('runs' in nexus_core_defaults) assert('basis_dir' in nexus_noncore_defaults) assert('pseudo_dir' in nexus_core_noncore_defaults) assert(object_eq(nexus_core,nexus_core_defaults)) assert(object_eq(nexus_noncore,nexus_noncore_defaults)) assert(object_eq(nexus_core_noncore,nexus_core_noncore_defaults)) from .simulation import Simulation assert(Simulation.sim_count==0) assert(len(Simulation.all_sims)==0) assert(len(Simulation.sim_directories)==0)
#end def check_final_state
[docs] def execute(command): from .execute import execute as nexus_execute import os # for python exe's, restrict pythonpath to this nexus repo ct = command.split() if len(ct)>0 and ct[0].strip('3').endswith('python'): pypath = os.path.abspath(os.path.join(__file__,'..','..')) command = 'PYTHONPATH='+pypath+' '+command out,err,rc = nexus_execute(command) if rc!=0: msg = '''Executed system command failed. Command: ======== {} stdout: ======= {} stderr: ======= {} Return code: ============ {} '''.format(command,out,err,rc) failed(msg) #end if return out,err,rc
#end def execute