diff --git a/Cassiopee/Converter/Converter/convertStruct2NGon.cpp b/Cassiopee/Converter/Converter/convertStruct2NGon.cpp index 14bc16bf9..f25f03cbd 100644 --- a/Cassiopee/Converter/Converter/convertStruct2NGon.cpp +++ b/Cassiopee/Converter/Converter/convertStruct2NGon.cpp @@ -383,7 +383,13 @@ PyObject* K_CONVERTER::convertStruct2NGon(PyObject* self, PyObject* args) // Clean connectivity E_Float tol = 1.e-12; - tpl = K_CONNECT::V_cleanConnectivity(varString, *f2, *cn2, "NGON", tol); + E_Bool rmOverlappingPts=true; E_Bool rmOrphanPts=false; + E_Bool rmDuplicatedFaces=true; E_Bool rmDuplicatedElts=false; + E_Bool rmDegeneratedFaces=true; E_Bool rmDegeneratedElts=false; + tpl = K_CONNECT::V_cleanConnectivity(varString, *f2, *cn2, "NGON", tol, + rmOverlappingPts, rmOrphanPts, + rmDuplicatedFaces, rmDuplicatedElts, + rmDegeneratedFaces, rmDegeneratedElts); delete f2; delete cn2; return tpl; } \ No newline at end of file diff --git a/Cassiopee/Converter/Converter/convertUnstruct2NGon.cpp b/Cassiopee/Converter/Converter/convertUnstruct2NGon.cpp index 7e7de32c0..a398fc160 100644 --- a/Cassiopee/Converter/Converter/convertUnstruct2NGon.cpp +++ b/Cassiopee/Converter/Converter/convertUnstruct2NGon.cpp @@ -378,7 +378,13 @@ PyObject* K_CONVERTER::convertUnstruct2NGon(PyObject* self, PyObject* args) // Clean connectivity E_Float tol = 1.e-12; - tpl = K_CONNECT::V_cleanConnectivity(varString, *f2, *cn2, "NGON", tol); + E_Bool rmOverlappingPts=true; E_Bool rmOrphanPts=false; + E_Bool rmDuplicatedFaces=true; E_Bool rmDuplicatedElts=false; + E_Bool rmDegeneratedFaces=false; E_Bool rmDegeneratedElts=false; + tpl = K_CONNECT::V_cleanConnectivity(varString, *f2, *cn2, "NGON", tol, + rmOverlappingPts, rmOrphanPts, + rmDuplicatedFaces, rmDuplicatedElts, + rmDegeneratedFaces, rmDegeneratedElts); delete f2; delete cn2; return tpl; } \ No newline at end of file diff --git a/Cassiopee/KCore/install b/Cassiopee/KCore/install index 849be45b4..2bb5c56d2 100755 --- a/Cassiopee/KCore/install +++ b/Cassiopee/KCore/install @@ -88,6 +88,8 @@ cp test/notifyInstall.py "$INSTALLPATH" cp test/notifyInstall "$INSTALLPATH" cp test/notifyValid.py "$INSTALLPATH" cp test/notifyValid "$INSTALLPATH" +cp test/compareSessionLogs.py "$INSTALLPATH" +cp test/compareSessionLogs "$INSTALLPATH" # Check installation python test/t1.py diff --git a/Cassiopee/KCore/test/compareSessionLogs b/Cassiopee/KCore/test/compareSessionLogs new file mode 100755 index 000000000..491e3bbf8 --- /dev/null +++ b/Cassiopee/KCore/test/compareSessionLogs @@ -0,0 +1,10 @@ +#! /bin/sh +if [ "$PYTHONEXE" != "" ]; then + alias python=$PYTHONEXE +fi +if test -e "$CASSIOPEE/Dist/bin/$ELSAPROD/compareSessionLogs.py" +then + python "$CASSIOPEE/Dist/bin/$ELSAPROD/compareSessionLogs.py" "$@" +else + python "$CASSIOPEE/Dist/bin/$ELSAPROD/compareSessionLogs.pyc" "$@" +fi diff --git a/Cassiopee/KCore/test/compareSessionLogs.py b/Cassiopee/KCore/test/compareSessionLogs.py index 99b8f36d4..b8ef464ff 100644 --- a/Cassiopee/KCore/test/compareSessionLogs.py +++ b/Cassiopee/KCore/test/compareSessionLogs.py @@ -12,9 +12,13 @@ def parseArgs(): # Create argument parser parser = argparse.ArgumentParser() parser.add_argument("-e", "--email", action="store_true", - help="Email results. Default: write to file") + help="Email results. Default: print in terminal") parser.add_argument("-l", "--logs", type=str, default='', help="Single-quoted logs to compare.") + parser.add_argument("-p", "--prod", type=str, default='', + help="Name of the production.") + parser.add_argument("-u", "--update", action="store_true", + help="Update valid. log on stck. Default: no update") # Parse arguments return parser.parse_args() @@ -38,6 +42,21 @@ def readGitInfo(filename): break return gitInfo +# Find a two session logs of validCassiopee for a given production +def findLogs(prodname): + import os + from glob import glob + validDataFolder = "/stck/cassiope/git/Cassiopee/Cassiopee/ValidData_{}".format(prodname) + if not os.access(validDataFolder, os.R_OK): + raise Exception("Session logs can't be retrieved in {}".format(validDataFolder)) + + logs = None + refLogs = sorted(glob(os.path.join(validDataFolder, "REF-session-*.log"))) + sessionLogs = sorted(glob(os.path.join(validDataFolder, "session-*.log"))) + if refLogs: logs = [refLogs[-1], sessionLogs[-1]] + elif len(sessionLogs) > 1: logs = sessionLogs[-2:] + return logs + # Read a session log of validCassiopee def readLog(filename): if not os.access(filename, os.R_OK): @@ -115,10 +134,16 @@ def stringify(test='', ref='', new=''): # Main if __name__ == '__main__': script_args = parseArgs() - script_args.logs = script_args.logs.split(' ') - if len(script_args.logs) != 2: - raise Exception("Two session logs must be provided using the flag -l " - "or --logs") + if script_args.prod: + script_args.logs = findLogs(script_args.prod) + if not(isinstance(script_args.logs, list) and len(script_args.logs) == 2): + raise Exception("Two session logs were not found for prod. {}".format( + script_args.prod)) + else: + script_args.logs = script_args.logs.split(' ') + if len(script_args.logs) != 2: + raise Exception("Two session logs must be provided using the flag -l " + "or --logs") # Read log files and git info refSession = readLog(script_args.logs[0]) @@ -141,7 +166,7 @@ def stringify(test='', ref='', new=''): # Find failed tests in newSession failedTests = sorted([k for k, v in newDict.items() if v[5] != 'OK']) - # Write differences to file or send an email + # Write differences to terminal or send an email baseState = 'OK' compStr = "" header = "\n".join("{}: {}".format(k,v) for k,v in gitInfo.items()) @@ -187,62 +212,63 @@ def stringify(test='', ref='', new=''): execTime.append([test, *getDiffExecTime(test, refDict[test], newDict[test])]) execTime.sort(key=lambda x: x[2]) - threshold = 50. - execTimeHeader = "\nExecution time - {:.0f}% threshold:\n{}\n".format(threshold, '-'*30) - compStr += execTimeHeader - compStr += "{} | {} | {} |\n{}\n".format(" "*60, "REF v Base".center(10), - "NEW v Base".center(10), '*'*88) - cmpt = 0 - for test in execTime: - if abs(test[2]) > threshold and abs(test[1]) < threshold: - compStr += stringify(test[0], str(test[1])+'%', str(test[2])+'%') - cmpt += 1 - if cmpt == 0: compStr += "[none]\n" + if script_args.email: + threshold = 50. + execTimeHeader = "\nExecution time - {:.0f}% threshold:\n{}\n".format(threshold, '-'*30) + compStr += execTimeHeader + compStr += "{} | {} | {} |\n{}\n".format(" "*60, "REF v Base".center(10), + "NEW v Base".center(10), '*'*88) + cmpt = 0 + for test in execTime: + if abs(test[2]) > threshold and abs(test[1]) < threshold: + compStr += stringify(test[0], str(test[1])+'%', str(test[2])+'%') + cmpt += 1 + if cmpt == 0: compStr += "[none]\n" - # If the state of the Base is OK, set the new session log to be the reference baseStateMsg = "" - exitStatus = 0 - if (any(st in baseState for st in ['OK', 'ADDITIONS', 'DELETIONS']) and - os.path.basename(script_args.logs[0]).startswith('REF-')): - if os.access(script_args.logs[0], os.W_OK): - import shutil - os.remove(script_args.logs[0]) - newRef = os.path.join(os.path.dirname(script_args.logs[1]), - 'REF-' + os.path.basename(script_args.logs[1])) - shutil.copyfile(script_args.logs[1], newRef) - else: exitStatus = 2 - prod = getProd(script_args.logs[1]) tlog, tlog2 = getTimeFromLog(script_args.logs[1]) + messageSubject = "[validCassiopee - {}] {} - State: {}".format(prod, tlog, baseState) + messageText = header + compStr + baseStateMsg if script_args.email: if baseStateMsg: baseStateMsg = '\n\n'+baseStateMsg try: from KCore.notify import notify notify(recipients=['vincent.casseau@onera.fr', 'christophe.benoit@onera.fr'], - messageSubject="[validCassiopee - {}] {} - " - "State: {}".format(prod, tlog, baseState), - messageText=header + compStr + baseStateMsg) + messageSubject=messageSubject, + messageText=messageText) except ImportError: raise SystemError("Error: KCore is required to import notify.") else: - filename = "./compSession_{}.txt".format(tlog2) - if os.access('./', os.W_OK): - print("Writing comparison to {}".format(filename)) - with open(filename, 'w') as f: f.write(header + compStr + baseStateMsg) + print("{0}\n|{1:^86}|\n{0}\n{2}".format(88*'-', messageSubject, messageText)) - # Amend state of the base in logs/validation_status.txt - logAllValids = "/stck/cassiope/git/logs/validation_status.txt" - entry = "{} - {} - {}\n".format(prod, tlog2, baseState) - if os.access(os.path.dirname(logAllValids), os.W_OK): - with open(logAllValids, 'r') as f: contents = f.readlines() - prodFound = False - for i, line in enumerate(contents): - if line.startswith(prod): - contents[i] = entry - prodFound = True - break + if script_args.update: + # If the state of the Base is OK, set the new session log to be the + # reference + exitStatus = 0 + if (any(st in baseState for st in ['OK', 'ADDITIONS', 'DELETIONS']) and + os.path.basename(script_args.logs[0]).startswith('REF-')): + if os.access(script_args.logs[0], os.W_OK): + import shutil + os.remove(script_args.logs[0]) + newRef = os.path.join(os.path.dirname(script_args.logs[1]), + 'REF-' + os.path.basename(script_args.logs[1])) + shutil.copyfile(script_args.logs[1], newRef) + else: exitStatus = 2 + + # Amend state of the base in logs/validation_status.txt + logAllValids = "/stck/cassiope/git/logs/validation_status.txt" + entry = "{} - {} - {}\n".format(prod, tlog2, baseState) + if os.access(os.path.dirname(logAllValids), os.W_OK): + with open(logAllValids, 'r') as f: contents = f.readlines() + prodFound = False + for i, line in enumerate(contents): + if line.startswith(prod): + contents[i] = entry + prodFound = True + break - if not prodFound: contents.append(entry) - with open(logAllValids, 'w') as f: f.writelines(contents) - - sys.exit(exitStatus) + if not prodFound: contents.append(entry) + with open(logAllValids, 'w') as f: f.writelines(contents) + + sys.exit(exitStatus)