initial upload
This commit is contained in:
5
test/testlagrit/__init__.py
Normal file
5
test/testlagrit/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .logger import log
|
||||
from .helper_functions import collect_test_dirs
|
||||
from .run_lagrit import run_lagrit
|
||||
from .find_lagrit import find_lagrit
|
||||
from .run_test import run_test
|
||||
620
test/testlagrit/check_test.py
Executable file
620
test/testlagrit/check_test.py
Executable file
@@ -0,0 +1,620 @@
|
||||
#! /n/local_linux/epd/bin/python2.7
|
||||
#
|
||||
# This script will not run with /usr/local/bin/python -> python3.2
|
||||
# for linux /n/local_linux/python2.5.1/bin/python
|
||||
#
|
||||
# default is now vers 3 in /usr/bin/python
|
||||
# for linux /n/local_linux/python2.5.1/bin/python
|
||||
# for mac /usr/bin/env python
|
||||
# for lanl machines /usr/bin/env python
|
||||
# for sgi /usr/lanl/bin/python
|
||||
# ------------------------------------------------------------------------------
|
||||
# Name: check_test.py
|
||||
# Usage: check_test.py (all dirs) or check_test.py dir1 (list dirs)
|
||||
# Last Modified: Jan 2008 by TAM
|
||||
#
|
||||
# writes differences to diffout_$OS.txt
|
||||
# and copies file to directory result_files
|
||||
#
|
||||
# Uses difflib.py providing diffs in four formats:
|
||||
# Current version uses unified
|
||||
#
|
||||
# ndiff: lists every line and highlights interline changes.
|
||||
# context: highlights clusters of changes in a before/after format.
|
||||
# unified: highlights clusters of changes in an inline format.
|
||||
# html: generates side by side comparison with change highlights.
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import fileinput, array, string, os, difflib, sys, datetime, time, copy
|
||||
|
||||
__all__ = ["fail", "rstrip", "diff_chunk", "Check"]
|
||||
|
||||
|
||||
def remove_junk_from_filestream(
|
||||
lines, banner="-----oOo-----", comment_chars=["#", "!", "*"]
|
||||
):
|
||||
"""
|
||||
Removes comments, headers, and whitespace from a list of strings,
|
||||
parsed from a lagrit.out file.
|
||||
"""
|
||||
newlines = []
|
||||
in_banner = False
|
||||
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
|
||||
if stripped == "":
|
||||
continue
|
||||
elif stripped[0] in comment_chars:
|
||||
continue
|
||||
elif banner in stripped:
|
||||
in_banner = not in_banner
|
||||
elif "log file: " in stripped:
|
||||
continue
|
||||
|
||||
if not in_banner:
|
||||
newlines.append(stripped)
|
||||
|
||||
return newlines[1:]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def fail(msg):
|
||||
out = sys.stderr.write
|
||||
out(msg + "\n\n")
|
||||
out(__doc__)
|
||||
return 0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def rstrip(line, JUNK="\n \t "):
|
||||
i = len(line)
|
||||
while i > 0 and line[i - 1] in JUNK:
|
||||
i -= 1
|
||||
return line[:i]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# compare using additional checks to diff
|
||||
|
||||
|
||||
def diff_chunk(rlines, tlines, rcnt, tcnt, wfile):
|
||||
|
||||
# need large epsilon to compare numbers 1.73469E+02 to 1.734693909E+02
|
||||
epsval = 0.001
|
||||
tmp = []
|
||||
tmp1 = []
|
||||
tmp2 = []
|
||||
ibad = 0
|
||||
ifa = 0
|
||||
ico = 0
|
||||
iju = 0
|
||||
count = 0
|
||||
debug = 0
|
||||
|
||||
# -Loop over each pair of lines 0 to tcnt
|
||||
count = max(tcnt, rcnt)
|
||||
for idx in range(count):
|
||||
rcount = 0
|
||||
tmp1 = "-"
|
||||
if idx < rcnt:
|
||||
rwords = rlines[idx].split(None)
|
||||
rcount = len(rwords)
|
||||
tmp = "-" + rlines[idx]
|
||||
tmp1 = tmp.rstrip()
|
||||
tcount = 0
|
||||
tmp2 = "+"
|
||||
if idx < tcnt:
|
||||
twords = tlines[idx].split(None)
|
||||
tcount = len(twords)
|
||||
tmp = "+" + tlines[idx]
|
||||
tmp2 = tmp.rstrip()
|
||||
|
||||
# for lines with same number of words, compare values word by word
|
||||
if tcount == rcount and tcount > 0:
|
||||
|
||||
ibad = 0
|
||||
# check to see if these are lines to skip
|
||||
if twords[0].find("*") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("comment line " + repr(idx) + tlines[idx])
|
||||
elif twords[0].find("#") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("comment line " + repr(idx) + tlines[idx])
|
||||
elif len(twords) < 2:
|
||||
iju = iju + 1
|
||||
if debug:
|
||||
print("junk line " + repr(idx) + tlines[idx])
|
||||
|
||||
else:
|
||||
|
||||
# Loop through word by word
|
||||
if debug:
|
||||
print("epsilon compare: %16.9f \n" % epsval)
|
||||
for i in range(len(rwords)):
|
||||
|
||||
if rwords[i].isalpha() and twords[i].isalpha():
|
||||
if rwords[i] == twords[i]:
|
||||
if debug:
|
||||
print("alpha same " + rwords[i] + " and " + twords[i])
|
||||
|
||||
else:
|
||||
if debug:
|
||||
print("alpha differ " + rwords[i] + " and " + twords[i])
|
||||
ibad = 1
|
||||
|
||||
elif rwords[i].isdigit() and twords[i].isdigit():
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"digits differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"digits same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("E+") > 0 and twords[i].find("E+") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers E+ differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers E+ same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("E-") > 0 and twords[i].find("E-") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers E- differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers E- same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("e+") > 0 and twords[i].find("e+") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers e+ differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers e+ same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("e-") > 0 and twords[i].find("e-") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers e- differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers e- same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
else:
|
||||
if rwords[i] != twords[i]:
|
||||
if debug:
|
||||
print("words differ " + rwords[i] + " and " + twords[i])
|
||||
# check for -0 and 0
|
||||
ibad = 1
|
||||
else:
|
||||
if debug:
|
||||
print("words same " + rwords[i] + " and " + twords[i])
|
||||
|
||||
# Done Loop through word by word
|
||||
|
||||
# for lines with different number of words, assume difference
|
||||
elif tcount != rcount and tcount > 0:
|
||||
if twords[0].find("*") > -1 or twords[0].find("#") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("Comment lines differs in length")
|
||||
else:
|
||||
if debug:
|
||||
print("Lines differ in length")
|
||||
ibad = 1
|
||||
|
||||
# compare for test and reference pair done
|
||||
ifa = ifa + ibad
|
||||
if debug or ibad:
|
||||
print(tmp1 + "\n" + tmp2 + "\n")
|
||||
wfile.write(tmp1 + "\n" + tmp2 + "\n")
|
||||
|
||||
if debug:
|
||||
print("end routine tcnt,ico,iju,ifa: ", tcnt, ico, iju, ifa)
|
||||
# -Done Loop over each pair of lines 0 to max(rcnt, tcnt)
|
||||
|
||||
return ifa, ico, iju
|
||||
|
||||
|
||||
#
|
||||
# alternate method for checking, save in case needed
|
||||
# squish all together to see if match
|
||||
# rline=string.join(rwords,"")
|
||||
# tline=string.join(twords,"")
|
||||
# if (rline == tline) : print "Match found: "+rline
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
##############################################################################
|
||||
# MAIN begin
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
def Check(target=None, test_dir: str = None, fail_threshold: int = 1):
|
||||
"""
|
||||
Checks run and reference outx3dgen files for differences.
|
||||
If differences are higher than some threshold, fails.
|
||||
|
||||
Arguments
|
||||
---------
|
||||
target (str):
|
||||
test_dir (str): Sub-directory to test. Default (None)
|
||||
tests all in current directory.
|
||||
"""
|
||||
|
||||
debug = 0
|
||||
JUNK = "\n \t"
|
||||
errList = []
|
||||
errmess = []
|
||||
rlines = []
|
||||
tlines = []
|
||||
nlines = 1
|
||||
rmspace = 0
|
||||
ierr = 0
|
||||
ifail = 0
|
||||
nfail = 0
|
||||
ndirs = 0
|
||||
result_dir = 0
|
||||
diffcopy = ""
|
||||
|
||||
# get platform
|
||||
osname = "unknown"
|
||||
osname = sys.platform.lower()
|
||||
if osname.find("linux") >= 0:
|
||||
ostag = "_lin"
|
||||
elif osname.find("sun") >= 0 or osname.find("sol") >= 0:
|
||||
ostag = "_sun"
|
||||
elif osname.find("darwin") >= 0:
|
||||
ostag = "_mac"
|
||||
elif osname.find("irix") >= 0:
|
||||
ostag = "_sgi"
|
||||
else:
|
||||
ostag = ""
|
||||
|
||||
# define top directory as current directory
|
||||
dtop = os.curdir
|
||||
dtop_path = os.getcwd()
|
||||
fout = dtop_path + "/diffout" + ostag + ".txt"
|
||||
|
||||
date = time.ctime()
|
||||
buff = "Start in directory: " + dtop_path + " at " + date
|
||||
|
||||
fref = "/reference/outx3dgen"
|
||||
ftest = "/outx3dgen"
|
||||
|
||||
# for each test directory
|
||||
# main loop
|
||||
|
||||
if target == dtop:
|
||||
dirnames = os.listdir(dtop)
|
||||
else:
|
||||
dirnames = [target]
|
||||
fout = dtop_path + "/diffout" + ostag + "_select.txt"
|
||||
|
||||
wfile = open(fout, "w")
|
||||
wfile.write(buff + "\n")
|
||||
wfile.close()
|
||||
|
||||
for name in dirnames:
|
||||
dwork = os.path.join(dtop, name)
|
||||
|
||||
# ---skip results directory until end
|
||||
if dwork == "./test_results":
|
||||
result_dir = 1
|
||||
|
||||
# ---check output for each directory and reference
|
||||
# header --- old reference file +++ new test file
|
||||
elif os.path.isdir(dwork):
|
||||
|
||||
# If configured for a single test,
|
||||
# then validate that we are parsing the correct test.
|
||||
if test_dir is not None:
|
||||
if dwork.split("/")[-1] != test_dir:
|
||||
continue
|
||||
|
||||
wfile = open(fout, "a")
|
||||
wfile.write("\n" + "Diff Summary " + "=" * 67 + "\n\n")
|
||||
ndirs = ndirs + 1
|
||||
buff = (
|
||||
repr(ndirs)
|
||||
+ " Check Directory "
|
||||
+ dwork
|
||||
+ " --------------------------"
|
||||
)
|
||||
print(buff)
|
||||
wfile.write(buff + "\n")
|
||||
|
||||
fromfile = dwork + fref
|
||||
tofile = dwork + ftest
|
||||
|
||||
# -------compare the output files
|
||||
if os.path.exists(tofile):
|
||||
|
||||
fromdate = time.ctime(os.stat(fromfile).st_mtime)
|
||||
todate = time.ctime(os.stat(tofile).st_mtime)
|
||||
fromlines = open(fromfile, "r", newline=None).readlines()
|
||||
tolines = open(tofile, "r", newline=None).readlines()
|
||||
|
||||
# Remove comments + banner
|
||||
fromlines = remove_junk_from_filestream(fromlines)
|
||||
tolines = remove_junk_from_filestream(tolines)
|
||||
|
||||
icomment = 0
|
||||
ijunk = 0
|
||||
ifail = 0
|
||||
iprintatt = 0
|
||||
|
||||
nlines = 0
|
||||
diff = difflib.unified_diff(
|
||||
fromlines, tolines, fromfile, tofile, fromdate, todate, nlines
|
||||
)
|
||||
diffcopy = difflib.unified_diff(
|
||||
fromlines, tolines, fromfile, tofile, fromdate, todate, nlines
|
||||
)
|
||||
|
||||
# --------
|
||||
# Loop through lines in diff result
|
||||
# write full result to diffout_*.txt, summary to screen
|
||||
# Check the chunk from diff formatted result
|
||||
# start with line @@ -lineno,chunksize +lineno,chunksize @@
|
||||
# followed by chunksize number of lines
|
||||
# later versions of diff allow a single number
|
||||
# ' 'for common line -in reference file +in test file
|
||||
|
||||
chunk = 0
|
||||
for line in diff:
|
||||
words = line.split(None)
|
||||
|
||||
# check to see if this is a new set of lines
|
||||
# if chunksize are equal, compare line pairs
|
||||
# otherwise print the whole chunk
|
||||
if words[0].find("@") > -1:
|
||||
oldlins = words[1].split(",")
|
||||
newlins = words[2].split(",")
|
||||
tlineno = int(newlins[0][1:])
|
||||
|
||||
# versions of python greater than 2.5 allow single value instead of pairs
|
||||
# avoid indexing number that may not exist
|
||||
if len(newlins) > 1:
|
||||
tnum = int(newlins[1])
|
||||
else:
|
||||
tnum = 0
|
||||
if len(oldlins) > 1:
|
||||
rnum = int(oldlins[1])
|
||||
else:
|
||||
rnum = 0
|
||||
|
||||
if tnum == rnum:
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
elif tnum > rnum:
|
||||
ifail = ifail + (tnum - rnum)
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
chdr = (
|
||||
chdr
|
||||
+ "\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum - rnum)
|
||||
+ " extra lines in this chunk."
|
||||
)
|
||||
elif rnum > tnum:
|
||||
ifail = ifail + (rnum - tnum)
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
chdr = (
|
||||
chdr
|
||||
+ "\n"
|
||||
+ "Test has "
|
||||
+ repr(rnum - tnum)
|
||||
+ " missing lines in this chunk."
|
||||
)
|
||||
chunk = 1
|
||||
nread = tnum + rnum
|
||||
iread = 0
|
||||
rcnt = 0
|
||||
tcnt = 0
|
||||
|
||||
if chunk == 1:
|
||||
# compare a chunk of line pairs output from diff
|
||||
# tlines are from test, rlines are from reference
|
||||
if line[0] == "-":
|
||||
rlines.append(line[1:])
|
||||
rcnt = rcnt + 1
|
||||
iread = iread + 1
|
||||
elif line[0] == "+":
|
||||
tlines.append(line[1:])
|
||||
tcnt = tcnt + 1
|
||||
iread = iread + 1
|
||||
else:
|
||||
if iread > 0:
|
||||
tmp = line.rstrip()
|
||||
print(tmp)
|
||||
wfile.write(tmp + "\n")
|
||||
|
||||
# chunk has been read
|
||||
if chunk == 1 and iread == nread:
|
||||
if debug:
|
||||
print(
|
||||
"Compare chunk ==============================================="
|
||||
)
|
||||
print(chdr)
|
||||
wfile.write(chdr + "\n")
|
||||
ifa, ico, iju = diff_chunk(
|
||||
rlines, tlines, rcnt, tcnt, wfile
|
||||
)
|
||||
ifail = ifail + ifa
|
||||
icomment = icomment + ico
|
||||
ijunk = ijunk + iju
|
||||
rlines = []
|
||||
tlines = []
|
||||
chunk = 0
|
||||
|
||||
count_1 = abs(int(repr(tcnt - ifa)))
|
||||
count_2 = abs(int(repr(tnum)))
|
||||
|
||||
buff = "Lines Essentially the Same: {0} out of {1}".format(
|
||||
min(count_1, count_2), max(count_1, count_2)
|
||||
)
|
||||
print(buff)
|
||||
|
||||
wfile.write(buff + "\n")
|
||||
|
||||
# --------
|
||||
# Done with loop through lines in diff result
|
||||
print("")
|
||||
if icomment:
|
||||
buff = repr(icomment) + " comment lines."
|
||||
wfile.write(buff + "\n")
|
||||
print("Removed " + buff)
|
||||
if ijunk:
|
||||
buff = repr(ijunk) + " junk lines."
|
||||
wfile.write(buff + "\n")
|
||||
print("Removed " + buff)
|
||||
if ifail:
|
||||
buff = repr(ifail) + " lines failed."
|
||||
wfile.write(buff + "\n")
|
||||
print(buff)
|
||||
errList.append(dwork)
|
||||
errmess.append(repr(ifail) + " lines failed.")
|
||||
ierr += 1
|
||||
else:
|
||||
buff = "No lines differ."
|
||||
wfile.write(buff + "\n")
|
||||
print(buff)
|
||||
buff = (
|
||||
repr(ndirs)
|
||||
+ " Done with Directory "
|
||||
+ dwork
|
||||
+ " -----------------------"
|
||||
)
|
||||
print(buff)
|
||||
wfile.write(buff + "\n")
|
||||
print(" ")
|
||||
|
||||
else:
|
||||
print("File missing: outx3dgen")
|
||||
errList.append(dwork)
|
||||
errmess.append("Missing LaGriT outx3dgen file.")
|
||||
ierr += 1
|
||||
nfail += 1
|
||||
|
||||
# -------done with compare
|
||||
if ifail > 0:
|
||||
nfail += 1
|
||||
wfile.write("Check done." + "\n\n")
|
||||
wfile.write(
|
||||
"Full Report from diff ========================================================="
|
||||
+ "\n\n"
|
||||
)
|
||||
wfile.writelines(diffcopy)
|
||||
wfile.write(
|
||||
"\n"
|
||||
+ "End Report from diff ========================================================="
|
||||
+ "\n"
|
||||
)
|
||||
wfile.close()
|
||||
|
||||
# ---done with work in lower directory
|
||||
|
||||
# end main loop
|
||||
wfile = open(fout, "a")
|
||||
if nfail:
|
||||
buff = (
|
||||
"All checks complete, "
|
||||
+ repr(nfail)
|
||||
+ " directories failed out of "
|
||||
+ repr(ndirs)
|
||||
)
|
||||
wfile.write(buff + "\n")
|
||||
print(buff)
|
||||
ERROR_CODE = 1 if nfail >= fail_threshold else 0
|
||||
sys.exit(ERROR_CODE)
|
||||
else:
|
||||
buff = "All " + repr(ndirs) + " successful!"
|
||||
wfile.write(buff + "\n")
|
||||
print(buff)
|
||||
if ierr > 0:
|
||||
i = 0
|
||||
print("--------------------------------------")
|
||||
for d in errList:
|
||||
buff = " " + errList[i] + " Error: " + errmess[i]
|
||||
wfile.write(buff + "\n")
|
||||
print(buff)
|
||||
print("--------------------------------------")
|
||||
i = i + 1
|
||||
|
||||
wfile.write("\n")
|
||||
wfile.close()
|
||||
if result_dir:
|
||||
b = os.system("cp -p " + fout + " ./test_results")
|
||||
print("Check done." + "\n" + "Full result written to: " + "\n")
|
||||
print(fout + "\n")
|
||||
print("and copied to ./test_results " + "\n")
|
||||
|
||||
else:
|
||||
print("Check done." + "\n" + "Full result written to " + fout + "\n")
|
||||
|
||||
|
||||
# end Main
|
||||
# ------------------------------------------------------------------------------
|
||||
459
test/testlagrit/diff.py
Normal file
459
test/testlagrit/diff.py
Normal file
@@ -0,0 +1,459 @@
|
||||
#! /n/local_linux/epd/bin/python2.7
|
||||
#
|
||||
# This script will not run with /usr/local/bin/python -> python3.2
|
||||
# for linux /n/local_linux/python2.5.1/bin/python
|
||||
#
|
||||
# default is now vers 3 in /usr/bin/python
|
||||
# for linux /n/local_linux/python2.5.1/bin/python
|
||||
# for mac /usr/bin/env python
|
||||
# for lanl machines /usr/bin/env python
|
||||
# for sgi /usr/lanl/bin/python
|
||||
# ------------------------------------------------------------------------------
|
||||
# Name: check_test.py
|
||||
# Usage: check_test.py (all dirs) or check_test.py dir1 (list dirs)
|
||||
# Last Modified: Jan 2008 by TAM
|
||||
#
|
||||
# writes differences to diffout_$OS.txt
|
||||
# and copies file to directory result_files
|
||||
#
|
||||
# Uses difflib.py providing diffs in four formats:
|
||||
# Current version uses unified
|
||||
#
|
||||
# ndiff: lists every line and highlights interline changes.
|
||||
# context: highlights clusters of changes in a before/after format.
|
||||
# unified: highlights clusters of changes in an inline format.
|
||||
# html: generates side by side comparison with change highlights.
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import fileinput, array, string, os, difflib, sys, datetime, time, copy
|
||||
from typing import List
|
||||
from .logger import log
|
||||
|
||||
__all__ = ["fail", "rstrip", "diff_chunk", "Check"]
|
||||
|
||||
|
||||
class WFileProp(object):
|
||||
"""
|
||||
In the original LaGriT diff, there
|
||||
was explicit file writing.
|
||||
This is a dummy class to mimic file writing
|
||||
while retaining the benefits of not having
|
||||
to modify any existing syntax.
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def write(self, *args):
|
||||
log.info(' '.join([str(x) for x in args]))
|
||||
|
||||
def remove_junk_from_filestream(
|
||||
lines, banner="-----oOo-----", comment_chars=["#", "!", "*"]
|
||||
):
|
||||
"""
|
||||
Removes comments, headers, and whitespace from a list of strings,
|
||||
parsed from a lagrit.out file.
|
||||
"""
|
||||
newlines = []
|
||||
in_banner = False
|
||||
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
|
||||
if stripped == "":
|
||||
continue
|
||||
elif stripped[0] in comment_chars:
|
||||
continue
|
||||
elif banner in stripped:
|
||||
in_banner = not in_banner
|
||||
elif "log file: " in stripped:
|
||||
continue
|
||||
|
||||
if not in_banner:
|
||||
newlines.append(stripped)
|
||||
|
||||
return newlines[1:]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def rstrip(line, JUNK="\n \t "):
|
||||
i = len(line)
|
||||
while i > 0 and line[i - 1] in JUNK:
|
||||
i -= 1
|
||||
return line[:i]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# compare using additional checks to diff
|
||||
|
||||
|
||||
def diff_chunk(rlines, tlines, rcnt, tcnt, wfile):
|
||||
|
||||
# need large epsilon to compare numbers 1.73469E+02 to 1.734693909E+02
|
||||
epsval = 0.001
|
||||
tmp = []
|
||||
tmp1 = []
|
||||
tmp2 = []
|
||||
ibad = 0
|
||||
ifa = 0
|
||||
ico = 0
|
||||
iju = 0
|
||||
count = 0
|
||||
debug = 0
|
||||
|
||||
# -Loop over each pair of lines 0 to tcnt
|
||||
count = max(tcnt, rcnt)
|
||||
for idx in range(count):
|
||||
rcount = 0
|
||||
tmp1 = "-"
|
||||
if idx < rcnt:
|
||||
rwords = rlines[idx].split(None)
|
||||
rcount = len(rwords)
|
||||
tmp = "-" + rlines[idx]
|
||||
tmp1 = tmp.rstrip()
|
||||
tcount = 0
|
||||
tmp2 = "+"
|
||||
if idx < tcnt:
|
||||
twords = tlines[idx].split(None)
|
||||
tcount = len(twords)
|
||||
tmp = "+" + tlines[idx]
|
||||
tmp2 = tmp.rstrip()
|
||||
|
||||
# for lines with same number of words, compare values word by word
|
||||
if tcount == rcount and tcount > 0:
|
||||
|
||||
ibad = 0
|
||||
# check to see if these are lines to skip
|
||||
if twords[0].find("*") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("comment line " + repr(idx) + tlines[idx])
|
||||
elif twords[0].find("#") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("comment line " + repr(idx) + tlines[idx])
|
||||
elif len(twords) < 2:
|
||||
iju = iju + 1
|
||||
if debug:
|
||||
print("junk line " + repr(idx) + tlines[idx])
|
||||
|
||||
else:
|
||||
|
||||
# Loop through word by word
|
||||
if debug:
|
||||
print("epsilon compare: %16.9f \n" % epsval)
|
||||
for i in range(len(rwords)):
|
||||
|
||||
if rwords[i].isalpha() and twords[i].isalpha():
|
||||
if rwords[i] == twords[i]:
|
||||
if debug:
|
||||
print("alpha same " + rwords[i] + " and " + twords[i])
|
||||
|
||||
else:
|
||||
if debug:
|
||||
print("alpha differ " + rwords[i] + " and " + twords[i])
|
||||
ibad = 1
|
||||
|
||||
elif rwords[i].isdigit() and twords[i].isdigit():
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"digits differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"digits same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("E+") > 0 and twords[i].find("E+") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers E+ differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers E+ same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("E-") > 0 and twords[i].find("E-") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers E- differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers E- same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("e+") > 0 and twords[i].find("e+") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers e+ differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers e+ same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
elif rwords[i].find("e-") > 0 and twords[i].find("e-") > 0:
|
||||
xval = abs(float(rwords[i]) - float(twords[i]))
|
||||
if xval > epsval:
|
||||
ibad = 1
|
||||
if debug:
|
||||
print(
|
||||
"numbers e- differ by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
elif debug:
|
||||
print(
|
||||
"numbers e- same by %16.9f , %s %s "
|
||||
% (xval, rwords[i], twords[i])
|
||||
)
|
||||
|
||||
else:
|
||||
if rwords[i] != twords[i]:
|
||||
if debug:
|
||||
print("words differ " + rwords[i] + " and " + twords[i])
|
||||
# check for -0 and 0
|
||||
ibad = 1
|
||||
else:
|
||||
if debug:
|
||||
print("words same " + rwords[i] + " and " + twords[i])
|
||||
|
||||
# Done Loop through word by word
|
||||
|
||||
# for lines with different number of words, assume difference
|
||||
elif tcount != rcount and tcount > 0:
|
||||
if twords[0].find("*") > -1 or twords[0].find("#") > -1:
|
||||
ico = ico + 1
|
||||
if debug:
|
||||
print("Comment lines differs in length")
|
||||
else:
|
||||
if debug:
|
||||
print("Lines differ in length")
|
||||
ibad = 1
|
||||
|
||||
# compare for test and reference pair done
|
||||
ifa = ifa + ibad
|
||||
if debug or ibad:
|
||||
print(tmp1 + "\n" + tmp2 + "\n")
|
||||
wfile.write(tmp1 + "\n" + tmp2 + "\n")
|
||||
|
||||
if debug:
|
||||
print("end routine tcnt,ico,iju,ifa: ", tcnt, ico, iju, ifa)
|
||||
# -Done Loop over each pair of lines 0 to max(rcnt, tcnt)
|
||||
|
||||
return ifa, ico, iju
|
||||
|
||||
def diff(output_test: str, output_reference: str):
|
||||
"""Computes diff between files.
|
||||
|
||||
Args:
|
||||
output_test (List[str]): Output file to be tested.
|
||||
output_reference (List[str]): Reference output file.
|
||||
"""
|
||||
|
||||
wfile = WFileProp()
|
||||
|
||||
fromfile = output_reference
|
||||
tofile = output_test
|
||||
|
||||
fromlines = tolines = None
|
||||
with open(fromfile, 'r', newline=None) as f:
|
||||
fromlines = f.readlines()
|
||||
with open(tofile, 'r', newline=None) as f:
|
||||
tolines = f.readlines()
|
||||
|
||||
fromdate = time.ctime(os.stat(fromfile).st_mtime)
|
||||
todate = time.ctime(os.stat(tofile).st_mtime)
|
||||
|
||||
# Remove comments + banner
|
||||
fromlines = remove_junk_from_filestream(fromlines)
|
||||
tolines = remove_junk_from_filestream(tolines)
|
||||
|
||||
icomment = 0
|
||||
ijunk = 0
|
||||
ifail = 0
|
||||
iprintatt = 0
|
||||
debug = 0
|
||||
JUNK = "\n \t"
|
||||
errList = []
|
||||
errmess = []
|
||||
rlines = []
|
||||
tlines = []
|
||||
nlines = 1
|
||||
rmspace = 0
|
||||
ierr = 0
|
||||
ifail = 0
|
||||
nfail = 0
|
||||
ndirs = 0
|
||||
result_dir = 0
|
||||
diffcopy = ""
|
||||
nlines = 0
|
||||
|
||||
diff = difflib.unified_diff(
|
||||
fromlines, tolines, fromfile, tofile, fromdate, todate, nlines
|
||||
)
|
||||
diffcopy = difflib.unified_diff(
|
||||
fromlines, tolines, fromfile, tofile, fromdate, todate, nlines
|
||||
)
|
||||
|
||||
# --------
|
||||
# Loop through lines in diff result
|
||||
# write full result to diffout_*.txt, summary to screen
|
||||
# Check the chunk from diff formatted result
|
||||
# start with line @@ -lineno,chunksize +lineno,chunksize @@
|
||||
# followed by chunksize number of lines
|
||||
# later versions of diff allow a single number
|
||||
# ' 'for common line -in reference file +in test file
|
||||
|
||||
chunk = 0
|
||||
for line in diff:
|
||||
words = line.split(None)
|
||||
|
||||
# check to see if this is a new set of lines
|
||||
# if chunksize are equal, compare line pairs
|
||||
# otherwise print the whole chunk
|
||||
if words[0].find("@") > -1:
|
||||
oldlins = words[1].split(",")
|
||||
newlins = words[2].split(",")
|
||||
tlineno = int(newlins[0][1:])
|
||||
|
||||
# versions of python greater than 2.5 allow single value instead of pairs
|
||||
# avoid indexing number that may not exist
|
||||
if len(newlins) > 1:
|
||||
tnum = int(newlins[1])
|
||||
else:
|
||||
tnum = 0
|
||||
if len(oldlins) > 1:
|
||||
rnum = int(oldlins[1])
|
||||
else:
|
||||
rnum = 0
|
||||
|
||||
if tnum == rnum:
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
elif tnum > rnum:
|
||||
ifail = ifail + (tnum - rnum)
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
chdr = (
|
||||
chdr
|
||||
+ "\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum - rnum)
|
||||
+ " extra lines in this chunk."
|
||||
)
|
||||
elif rnum > tnum:
|
||||
ifail = ifail + (rnum - tnum)
|
||||
chdr = (
|
||||
"\n"
|
||||
+ "Test has "
|
||||
+ repr(tnum)
|
||||
+ " diffs at line "
|
||||
+ repr(tlineno)
|
||||
+ " >>"
|
||||
)
|
||||
chdr = (
|
||||
chdr
|
||||
+ "\n"
|
||||
+ "Test has "
|
||||
+ repr(rnum - tnum)
|
||||
+ " missing lines in this chunk."
|
||||
)
|
||||
chunk = 1
|
||||
nread = tnum + rnum
|
||||
iread = 0
|
||||
rcnt = 0
|
||||
tcnt = 0
|
||||
|
||||
if chunk == 1:
|
||||
# compare a chunk of line pairs output from diff
|
||||
# tlines are from test, rlines are from reference
|
||||
if line[0] == "-":
|
||||
rlines.append(line[1:])
|
||||
rcnt = rcnt + 1
|
||||
iread = iread + 1
|
||||
elif line[0] == "+":
|
||||
tlines.append(line[1:])
|
||||
tcnt = tcnt + 1
|
||||
iread = iread + 1
|
||||
else:
|
||||
if iread > 0:
|
||||
tmp = line.rstrip()
|
||||
wfile.write(tmp + "\n")
|
||||
|
||||
# chunk has been read
|
||||
if chunk == 1 and iread == nread:
|
||||
if debug:
|
||||
print(
|
||||
"Compare chunk ==============================================="
|
||||
)
|
||||
wfile.write(chdr + "\n")
|
||||
ifa, ico, iju = diff_chunk(
|
||||
rlines, tlines, rcnt, tcnt, wfile
|
||||
)
|
||||
ifail = ifail + ifa
|
||||
icomment = icomment + ico
|
||||
ijunk = ijunk + iju
|
||||
rlines = []
|
||||
tlines = []
|
||||
chunk = 0
|
||||
|
||||
count_1 = abs(int(repr(tcnt - ifa)))
|
||||
count_2 = abs(int(repr(tnum)))
|
||||
|
||||
buff = "Lines Essentially the Same: {0} out of {1}".format(
|
||||
min(count_1, count_2), max(count_1, count_2)
|
||||
)
|
||||
wfile.write(buff + "\n")
|
||||
|
||||
# --------
|
||||
# Done with loop through lines in diff result
|
||||
if icomment:
|
||||
buff = repr(icomment) + " comment lines."
|
||||
wfile.write(buff + "\n")
|
||||
if ijunk:
|
||||
buff = repr(ijunk) + " junk lines."
|
||||
wfile.write(buff + "\n")
|
||||
if ifail:
|
||||
buff = repr(ifail) + " lines failed."
|
||||
wfile.write(buff + "\n")
|
||||
wfile.write(repr(ifail) + " lines failed.")
|
||||
ierr += 1
|
||||
return False
|
||||
else:
|
||||
buff = "No lines differ."
|
||||
wfile.write(buff + "\n")
|
||||
|
||||
return True
|
||||
41
test/testlagrit/find_lagrit.py
Normal file
41
test/testlagrit/find_lagrit.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import sys
|
||||
from distutils.spawn import find_executable
|
||||
from .logger import log
|
||||
|
||||
def find_lagrit(start_dir: str) -> str:
|
||||
"""Attempts to find LaGriT.
|
||||
|
||||
Args:
|
||||
start_dir (str): 'Hint' directory to search from.
|
||||
|
||||
Returns:
|
||||
str: Path to LaGriT.
|
||||
"""
|
||||
|
||||
search_dirs = []
|
||||
exe_candidates = []
|
||||
|
||||
if start_dir.lower().replace('/','').replace('\\','').endswith('test'):
|
||||
for p in ["..", "../src", "../build", "../install"]:
|
||||
search_dirs.append(os.path.join(start_dir, p))
|
||||
|
||||
for p in search_dirs:
|
||||
for exe_name in ["lagrit", "lagrit.exe"]:
|
||||
candidate = find_executable(exe_name, path=p)
|
||||
if candidate is not None:
|
||||
exe_candidates.append(candidate)
|
||||
|
||||
for exe_name in ["lagrit", "lagrit.exe"]:
|
||||
candidate = find_executable(exe_name, path=p)
|
||||
|
||||
if candidate is not None:
|
||||
exe_candidates.append(candidate)
|
||||
|
||||
log.debug("Found LaGriT at: %s" % str(exe_candidates))
|
||||
|
||||
if len(exe_candidates):
|
||||
log.info("Choosing LaGriT at %s" % exe_candidates[0])
|
||||
return exe_candidates[0]
|
||||
|
||||
raise FileNotFoundError("Could not find LaGriT!")
|
||||
40
test/testlagrit/helper_functions.py
Normal file
40
test/testlagrit/helper_functions.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
|
||||
def collect_test_dirs(test_root: str, test_levels: List[int]) -> List[str]:
|
||||
"""Returns a list of test directories.
|
||||
|
||||
Args:
|
||||
test_root (str): Should be `{LAGRIT_ROOT}/test/`
|
||||
test_levels (List): A list containing one or more of [1, 2, 3]
|
||||
|
||||
Returns:
|
||||
List[str]: A list of absolute paths to valid test directories.
|
||||
"""
|
||||
all_test_dirs = []
|
||||
|
||||
# Get absolute path of 'level01', 'level02', etc.
|
||||
# test_levels = [os.path.join(test_root, level) for level in test_levels]
|
||||
|
||||
for level in test_levels:
|
||||
if isinstance(level, int):
|
||||
level = "level%02d" % level
|
||||
|
||||
level_abspath = os.path.join(test_root, level)
|
||||
assert os.path.isdir(level_abspath), "Could not find level: %s" % level_abspath
|
||||
|
||||
# Grabs and appends all subfolders in a 'level0X/' directory
|
||||
# Requires each subfolder to have a 'reference/' directory
|
||||
for test_dir in sorted(os.listdir(level_abspath)):
|
||||
|
||||
if test_dir == "test_results":
|
||||
continue
|
||||
|
||||
test_dir = os.path.join(level_abspath, test_dir)
|
||||
reference_dir = os.path.join(test_dir, "reference/")
|
||||
|
||||
if os.path.isdir(test_dir) and os.path.isdir(reference_dir):
|
||||
all_test_dirs.append(test_dir)
|
||||
|
||||
return all_test_dirs
|
||||
5
test/testlagrit/logger.py
Normal file
5
test/testlagrit/logger.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import logging
|
||||
|
||||
# Configure the logger that will write test info to a file
|
||||
logging.basicConfig(filename='lagrit-tests.log', level=logging.DEBUG, format='%(levelname)s:%(message)s')
|
||||
log = logging.getLogger(__name__)
|
||||
58
test/testlagrit/run_lagrit.py
Normal file
58
test/testlagrit/run_lagrit.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import subprocess
|
||||
from typing import Any
|
||||
from collections.abc import Iterable
|
||||
from .logger import log
|
||||
|
||||
# $ lagrit < infile > outfile
|
||||
|
||||
|
||||
def run_lagrit(lagrit_exe: str, working_directory: str, infile: str = "input.lgi", flags: str = None):
|
||||
"""Calls the LaGriT executable.
|
||||
|
||||
Args:
|
||||
lagrit_exe (str): Path to the LaGriT executable binary.
|
||||
flags (Any[str, Iterable], optional): Optional flags to pass to LaGriT. Defaults to None.
|
||||
|
||||
"""
|
||||
# Verify the path to LaGriT exists and is a file
|
||||
if not os.path.isfile(lagrit_exe):
|
||||
raise FileNotFoundError(
|
||||
"Invalid path - LaGriT does not exist at %s" % lagrit_exe
|
||||
)
|
||||
|
||||
# Check test directory exists
|
||||
if not os.path.isdir(working_directory):
|
||||
raise FileNotFoundError("Invalid path - no directory exists: %s" % working_directory)
|
||||
|
||||
# Check the infile exists in the desired working directory
|
||||
if not os.path.isabs(infile):
|
||||
if not os.path.isfile(os.path.join(working_directory, infile)):
|
||||
raise FileNotFoundError("Invalid path - %s does not exist" % (os.path.join(working_directory, infile)))
|
||||
|
||||
# Make sure flags are in a list format
|
||||
if isinstance(flags, str):
|
||||
flags = flags.split(' ')
|
||||
if not isinstance(flags, Iterable):
|
||||
flags = []
|
||||
|
||||
stdin = None
|
||||
with open(os.path.join(working_directory, infile), 'r') as f:
|
||||
stdin = f.read()
|
||||
|
||||
log.info("Running test case at %s" % working_directory)
|
||||
log.info(" ".join([lagrit_exe, *flags]))
|
||||
|
||||
# Finally, call LaGriT
|
||||
stdout, stderr = subprocess.Popen(
|
||||
[lagrit_exe, *flags],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
cwd=working_directory,
|
||||
).communicate(stdin.encode('utf-8'))
|
||||
|
||||
#log.info("stdout = " + stdout.decode())
|
||||
#log.info("stderr = " + stderr.decode())
|
||||
|
||||
return (stdout.decode(), stderr.decode())
|
||||
14
test/testlagrit/run_test.py
Normal file
14
test/testlagrit/run_test.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
from .run_lagrit import run_lagrit
|
||||
from .diff import diff
|
||||
from .logger import log
|
||||
|
||||
def run_test(lagrit_exe: str, test_dir: str, logfile: str = "logx3dgen", outfile: str = "outx3dgen"):
|
||||
log.info("Running %s" % test_dir)
|
||||
flags="-log %s -out %s" % (logfile, outfile)
|
||||
stdout, stderr = run_lagrit(lagrit_exe, test_dir, flags=flags)
|
||||
|
||||
test_output = os.path.join(test_dir, outfile)
|
||||
reference_output = os.path.join(test_dir, 'reference', 'outx3dgen')
|
||||
|
||||
return diff(test_output, reference_output)
|
||||
Reference in New Issue
Block a user